Open libraries
Read in data
Read in tracking spreadsheet
Show code
db = read_excel(path = "Dataset 1.27.24.xlsx")
db <- db %>%
filter(CAR.T.Product.Type == "Breyanzi" | CAR.T.Product.Type == "Yescarta") %>% # Include both Breyanzi and Yescarta
filter(Acalabrutinib ==0) %>% # Remove patients treated on FH10418 RG1006269 acalabrutinib + yescarta
filter(NKTR == 0) %>% # Remove patients treated on FH10802 RG1122036 NKTR-255 + breyanzi
filter(Anakinra == 0) %>% # Remove patients treated on FH10373 RG1006866 Breyanzi + Anakinra
filter(Disease != "BL" & Disease != "FL") %>% # Remove BL and FL
filter(Infused == 1) %>% # Only include patients who received a CAR-T product
mutate(
Best.CR = ifelse(Best.response=="CR","1","0"),
Best.PR = ifelse(Best.response=="PR","1","0"),
Best.PD = ifelse(Best.response=="PD","1","0"),
CRS.2.to.4 = ifelse(CRS.grade >=2,"1","0"),
ICANS.2.to.4 = ifelse(ICANS.grade >=2, "1","0"),
CRS.grade = factor(CRS.grade, levels = c("0","1","2","3","4")),
ICANS.grade = factor(ICANS.grade, levels = c("0","1","2","3","4")),
DOB = ymd(DOB),
Leuka.date = ymd(Leuka.date),
LD.date = ymd(LD.date),
Infusion.Date = ymd(Infusion.Date),
CRS.date = ymd(CRS.date),
ICANS.date = ymd(ICANS.date),
Initial.response.date = ymd(Initial.response.date),
Date.of.relapse = ymd(Date.of.relapse),
Date.of.death.or.last.contact = ymd(Date.of.death.or.last.contact),
CRS.day = as.numeric(ifelse(CRS.grade !=0, CRS.date - Infusion.Date,"")),
ICANS.day = as.numeric(ifelse(ICANS.grade !=0, ICANS.date - Infusion.Date,"")),
CRS.ICANS.diff = as.numeric(ifelse(CRS.grade != 0 & ICANS.grade !=0, ICANS.date - CRS.date,"")),
Days.to.DLC2 = Date.of.death.or.last.contact - Infusion.Date,
Days.to.relapse2 = Date.of.relapse - Infusion.Date,
Days.to.response = Initial.response.date - Infusion.Date,
Vein.to.vein.time = Infusion.Date - Leuka.date,
Bulky = ifelse(Largest.lesion >=5, "1","0")
#Best.response = factor(Best.response, levels = c("CR","PR","SD","Mixed","PD","")),
#Initial.response = factor(Initial.response, levels = c("CR","PR","SD","Mixed","PD",""))
)
db$Best.CR <- as.factor(db$Best.CR)
db$Best.PR <- as.factor(db$Best.PR)
db$Best.PD <- as.factor(db$Best.PD)
Read in demographic data and join with master dataset
Show code
demographics = read_excel(path = "/Users/aportugu/Desktop/CD19 project/EMR data/demographics/2023.12.13.demographics.xlsx")
dataset <-
left_join(
x = db,
y = select(demographics, "ArrivalDate", "uwid"),
by = "uwid"
)
dataset <- dataset %>%
mutate(
ArrivalDate = ymd(ArrivalDate),
Arrival.to.vein.time = Infusion.Date - ArrivalDate
)
Read in product order data and join with master dataset
Show code
Order = read_excel(path = "/Users/aportugu/Desktop/CD19 project/EMR data/Order date/Order date.xlsx")
dataset <-
left_join(
x = dataset,
y = select(Order, "Order.date", "uwid"),
by = "uwid"
)
dataset <- dataset %>%
mutate(
Order.date = ymd(Order.date),
Order.to.vein.time = Infusion.Date - Order.date
)
Read in admissions data and join with master dataset
Show code
admissions = read_excel(path = "/Users/aportugu/Desktop/CD19 project/EMR data/admissions/2023.12.13.Admissions.xlsx")
inpatient.duration.df <- admissions %>% # Data frame for all admissions between days 0 and 30
filter(admitDay %in% (0:30) & PatientClass == "Inpatient") %>%
group_by(uwid) %>%
summarise(inpatient.duration = sum(days), admissions = n())
elective.admission.df <- admissions %>% # Data frame for elective admissions only
filter(admitDay == 0 & PatientClass == "Inpatient") %>% # Inpatient admission on day 0
group_by(uwid) %>%
summarise(elective.duration = sum(days)) %>%
mutate(elective.admission = 1)
dataset <- # Join all admission data
left_join(
x = dataset,
y = inpatient.duration.df,
by = "uwid",
)
dataset <- # Join elective admission data
left_join(
x = dataset,
y = elective.admission.df,
by = "uwid"
)
dataset <- dataset %>%
replace_na(list(inpatient.duration = 0, admissions = 0, elective.duration = 0, elective.admission = 0)) # Get rid of NA values
Read in CBC data
Show code
CBC = read_excel(path = "/Users/aportugu/Desktop/CD19 project/EMR data/labs/2023.12.13.hems.xlsx")
CBC$date = ymd(CBC$date)
CBC.df <- CBC %>% # Data frame for CBCs between days 0 and 30
filter(anc != "" & day >=0 & day <=30) %>%
group_by(uwid) %>%
summarise(CBC.count = n(), WBC.min = min(wbc, na.rm=TRUE) / 1000, Plt.min = min(TotPlateletCnt, na.rm=TRUE) / 1000, Hgb.min = min(HgbAmt, na.rm=TRUE), ANC.min = min(anc, na.rm=TRUE) / 1000, ALC.min = min(lym, na.rm=TRUE) / 1000 )
CBC.30.df <- CBC %>% # Data frame for CBCs between days 0 and 30
filter(anc != "" & day >=25 & day <=30) %>%
group_by(uwid) %>%
slice_max(day, with_ties = FALSE) %>%
summarise(CBC.count = n(), WBC.30 = max(wbc, na.rm=TRUE) / 1000, Plt.30 = max(TotPlateletCnt, na.rm=TRUE) / 1000, Hgb.30 = max(HgbAmt, na.rm=TRUE), ANC.30 = max(anc, na.rm=TRUE) / 1000, ALC.30 = min(lym, na.rm=TRUE) / 1000 )
WBC.nadir.df <- CBC %>%
filter(wbc != "" & day >=0 & day <=30) %>%
group_by(uwid) %>%
slice_min(wbc, with_ties = FALSE) %>%
transmute(WBC_day_nadir = day)%>%
select(WBC_day_nadir, uwid)
dataset <- # Join CBC data
left_join(
x = dataset,
y = CBC.df,
by = "uwid"
)
dataset <- # Join ANC day nadir
left_join(
x = dataset,
y = WBC.nadir.df,
by = "uwid"
)
dataset <- # Join ANC day nadir
left_join(
x = dataset,
y = CBC.30.df,
by = "uwid"
)
neutropenic.df <- CBC %>%
filter(anc != "" & anc <500 & day >=0 & day <=30) %>%
group_by(uwid) %>%
summarise(
neutropenic.days = n()
)
dataset <- # Join neutropenic days info
left_join(
x = dataset,
y = neutropenic.df,
by = "uwid"
) %>%
mutate(
neutropenic.days = ifelse(is.na(neutropenic.days),0,neutropenic.days)
)
CBC.d0.df <- CBC %>% ## Data frame for day 0
filter(day == 0) %>%
group_by(uwid) %>%
summarise(ANC.d0 = mean(anc, na.rm=TRUE) / 1000, ALC.d0 = mean (lym, na.rm=TRUE) / 1000)
dataset <-
left_join(
x = dataset,
y = CBC.d0.df,
by = "uwid"
) %>%
mutate(
ANC.d0 = ifelse(ANC.d0 == "NaN", NA, ANC.d0),
ALC.d0 = ifelse(ALC.d0 == "NaN", NA, ANC.d0)
)
Read in other lab data
Show code
labs = read_excel(path = "/Users/aportugu/Desktop/CD19 project/EMR data/labs/2023.12.13.labs.xlsx")
labs$date = ymd(labs$date)
labs.df <- labs %>% # Data frame for labs between days 0 and 30
filter(day >=0 & day <=30) %>%
group_by(uwid) %>%
summarise(labs.count = n() , ALT.max = max(ALT_u_l, na.rm=TRUE), AST.max = max(AST_u_l, na.rm=TRUE), cre.min = min(CRE_mg_dl, na.rm=TRUE), cre.max = max(CRE_mg_dl, na.rm=TRUE), CRP.max = max(CRP_mg_l, na.rm=TRUE), ddimer.max = max(d_dimer, na.rm=TRUE), ferritin.max = max(ferritin_ng_ml, na.rm=TRUE), fibrinogen.min = min(fibrinogen_mg_dl, na.rm=TRUE), IL6.max = max(IL6_pg_ml, na.rm=TRUE), LDH.max = max(LD_u_l, na.rm=TRUE), LDH.min = min(LD_u_l, na.rm=TRUE), trop.max = max(troponin_ng_ml, na.rm=TRUE) )
labs.d3.df <- labs %>% ## Data frame for day 3
filter(day == 3) %>%
group_by(uwid) %>%
summarise(ferritin.d3 = mean(ferritin_ng_ml, na.rm=TRUE), LDH.d3 = mean(LD_u_l, na.rm=TRUE), IL6.d3 = max(IL6_pg_ml, na.rm=TRUE), CRP.d3 = max(CRP_mg_l, na.rm=TRUE))
labs.d0.df <- labs %>% ## Data frame for day 0
filter(day == 0) %>%
group_by(uwid) %>%
summarise(ferritin.d0 = mean(ferritin_ng_ml, na.rm=TRUE), LDH.d0 = mean(LD_u_l, na.rm=TRUE), IL6.d0 = max(IL6_pg_ml, na.rm=TRUE) )
labs.df[sapply(labs.df, is.infinite)] <- NA ## Change any -inf values to NA
labs.d3.df[sapply(labs.d3.df, is.infinite)] <- NA ## Change any -inf values to NA
labs.d0.df[sapply(labs.d0.df, is.infinite)] <- NA ## Change any -inf values to NA
dataset <-
left_join(
x = dataset,
y = labs.df,
by = "uwid"
)
dataset <- # Join ANC day nadir
left_join(
x = dataset,
y = labs.d3.df,
by = "uwid"
)
dataset <- # Join ANC day nadir
left_join(
x = dataset,
y = labs.d0.df,
by = "uwid"
)
Read in blood culture data
Show code
blood.culture = read_excel(path = "/Users/aportugu/Desktop/CD19 project/EMR data/id/2023.12.13.ID_ALL.xlsx")
blood.culture$date = ymd(blood.culture$date)
Pos.BCx <- blood.culture %>%
select(uwid, bact, organism, date, day) %>%
group_by(uwid) %>%
filter(bact == "1" & day >=0) %>%
distinct() %>%
slice_min(day) %>%
transmute(
uwid,
Pos.BCx = 1,
BCx.day = day,
BCx.date = date,
BCx.organism = organism,
)
Pos.CMV <- blood.culture %>%
select(uwid, viral, organism, date, day, value) %>%
group_by(uwid) %>%
filter(organism == "CMV" & day >=0) %>%
distinct() %>%
summarise(CMV.first.day = min(day, na.rm = TRUE), CMV.last.day = max(day, na.rm = TRUE), CMV.peak.level = max(value, na.rm = TRUE)) %>%
mutate(
CMV = 1
)
Pos.CMV[sapply(Pos.CMV, is.infinite)] <- NA ## Change any -inf values to NA
dataset <- # Join BCx data
left_join(
x = dataset,
y = Pos.BCx,
by = "uwid"
)
dataset <- # Join CMV data
left_join(
x = dataset,
y = Pos.CMV,
by = "uwid"
)
dataset <- dataset %>%
mutate(
Pos.BCx = ifelse( is.na(Pos.BCx) ,0,Pos.BCx),
CMV = ifelse( is.na(CMV), 0, CMV ),
CMV.peak.level = ifelse( is.na(CMV.peak.level), 0, CMV.peak.level)
)
Determine the baseline pre-LD lab values
Show code
avg = 1
days = 14
CBC.with.LD.date <- # join the LD dates to the CBC dataframe
left_join(
x = CBC,
y = dataset %>% select(uwid, LD.date),
by = "uwid"
)
## CBC
preLD.CBC.df <- CBC.with.LD.date %>%
filter(LD.date >= date & LD.date - date <days & !is.na(wbc) ) %>%
group_by(uwid) %>%
slice_min(LD.date - date, n=avg) %>%
summarise(WBC.preLD = mean(wbc, na.rm=TRUE) / 1000, Plt.preLD = mean(TotPlateletCnt, na.rm=TRUE) / 1000, Hgb.preLD = mean(HgbAmt, na.rm=TRUE))
dataset <- # join pre-LD CBC lab values
left_join(
x = dataset,
y = preLD.CBC.df,
by = "uwid"
)
## Differential (ALC and ANC)
preLD.ALC.ANC.df <- CBC.with.LD.date %>%
filter(LD.date >= date & LD.date - date <days & !is.na(anc) ) %>%
group_by(uwid) %>%
slice_min(LD.date - date, n=avg) %>%
summarise(ANC.preLD = mean(anc, na.rm=TRUE) / 1000, ALC.preLD = mean (lym, na.rm=TRUE) / 1000)
dataset <- # join pre-LD CBC lab values
left_join(
x = dataset,
y = preLD.ALC.ANC.df,
by = "uwid"
)
labs.with.LD.date <- # join the LD dates to the labs dataframe
left_join(
x = labs,
y = dataset %>% select(uwid, LD.date),
by = "uwid"
)
## LDH
preLD.LDH.df <- labs.with.LD.date %>%
filter(LD.date >= date & LD.date - date <days & !is.na(LD_u_l) ) %>%
group_by(uwid) %>%
slice_min(LD.date - date, n=avg, na_rm = TRUE) %>%
summarise(LDH.preLD = mean(LD_u_l, na.rm=TRUE))
dataset <- # join pre-LD lab values
left_join(
x = dataset,
y = preLD.LDH.df,
by = "uwid"
)
dataset <- dataset %>%
mutate(
High.LDH = ifelse(LDH.preLD >=210,1,0),
LDH.status = factor( case_when(
LDH.preLD <210 ~ 0,
LDH.preLD >=210 & LDH.preLD <=420 ~ 1,
LDH.preLD >420 ~ 2),
levels = c(0,1,2) )
)
## Renal function
preLD.Cr.df <- labs.with.LD.date %>%
filter(LD.date >= date & LD.date - date <days & !is.na(CRE_mg_dl) ) %>%
group_by(uwid) %>%
slice_min(LD.date - date, n=avg, na_rm = TRUE) %>%
summarise(cre.preLD = mean(CRE_mg_dl, na.rm=TRUE))
dataset <- # join pre-LD lab values
left_join(
x = dataset,
y = preLD.Cr.df,
by = "uwid"
)
## Ferritin
preLD.ferritin.df <- labs.with.LD.date %>%
filter(LD.date >= date & LD.date - date <days & !is.na(ferritin_ng_ml) ) %>%
group_by(uwid) %>%
slice_min(LD.date - date, n=avg, na_rm = TRUE) %>%
summarise(ferritin.preLD = mean(ferritin_ng_ml, na.rm=TRUE))
dataset <- # join pre-LD lab values
left_join(
x = dataset,
y = preLD.ferritin.df,
by = "uwid"
)
## CRP
preLD.CRP.df <- labs.with.LD.date %>%
filter(LD.date >= date & LD.date - date <days & !is.na(CRP_mg_l) ) %>%
group_by(uwid) %>%
slice_min(LD.date - date, n=avg, na_rm = TRUE) %>%
summarise(CRP.preLD = mean(CRP_mg_l, na.rm=TRUE))
dataset <- # join pre-LD lab values
left_join(
x = dataset,
y = preLD.CRP.df,
by = "uwid"
)
Read in BP data and determine pre-LD baseline
Show code
BP = read_excel(path = "/Users/aportugu/Desktop/CD19 project/EMR data/vs/2023.12.13.BP.xlsx")
BP$date = ymd(BP$date)
BP.post.df <- BP %>% # Data frame for labs between days 0 and 30
filter(day >=0 & day <=30) %>%
group_by(uwid) %>%
summarise( BP.count = n() , SBP.max = max(SBP, na.rm=TRUE), DBP.max = max(DBP, na.rm=TRUE), SBP.min = min(SBP, na.rm=TRUE), DBP.min = min(DBP, na.rm=TRUE) )
dataset <- # post-infusion values
left_join(
x = dataset,
y = BP.post.df,
by = "uwid"
)
BP.with.LD.date <- # join the LD dates to the BP dataframe
left_join(
x = BP,
y = dataset %>% select(uwid, LD.date),
by = "uwid"
)
preLD.BP.df <- BP.with.LD.date %>%
filter(LD.date >= date & LD.date - date <10) %>% ## Within 14 days prior to LD
group_by(uwid) %>%
slice_min(LD.date - date, n=3) %>%
summarise(SBP.preLD = mean(SBP, na.rm=TRUE), DBP.preLD = mean(DBP, na.rm=TRUE) )
dataset <- # join pre-LD BP lab values
left_join(
x = dataset,
y = preLD.BP.df,
by = "uwid"
) %>%
mutate(
MAP.preLD = DBP.preLD + (SBP.preLD - DBP.preLD)/3,
MAP.min = DBP.min + (SBP.min - DBP.min)/3
)
Read in tocilizumab data
Show code
toci = read_excel(path = "/Users/aportugu/Desktop/CD19 project/EMR data/meds/2023.12.13.tocilizumab.xlsx")
toci$date = ymd(toci$date)
toci.df <- toci %>%
select(uwid, date, day, Dose) %>%
group_by(uwid) %>%
filter(day >=0) %>%
summarise(toci.first.day = min(day, na.rm=TRUE), toci.first.date = min(date, na.rm=TRUE), toci.last.day = max(day, na.rm=TRUE), toci.last.date = max(date, na.rm=TRUE), toci.doses = n())
dataset <- # join pre-LD CBC lab values
left_join(
x = dataset,
y = toci.df,
by = "uwid"
) %>%
mutate(
toci.doses = ifelse(is.na(toci.doses),0,toci.doses) # Set NA values to 0
)
Read in dexamethasone data
Show code
dex = read_excel(path = "/Users/aportugu/Desktop/CD19 project/EMR data/meds/2023.12.13.dexamethasone.xlsx")
dex$date = ymd(dex$date)
dex.df <- dex %>%
select(uwid, date, day, Dose, AdministrationRoute) %>%
group_by(uwid) %>%
filter(day >=0 & AdministrationRoute != "Oral" & AdministrationRoute != "PO" & AdministrationRoute != "EYE-Left" & AdministrationRoute != "EYE-Right") %>%
summarise(dex.first.day = min(day, na.rm=TRUE), dex.first.date = min(date, na.rm=TRUE), dex.last.day = max(day, na.rm=TRUE), dex.last.date = max(date, na.rm=TRUE), dex.doses = n())
dataset <- # join pre-LD CBC lab values
left_join(
x = dataset,
y = dex.df,
by = "uwid"
) %>%
mutate(
dex.doses = ifelse(is.na(dex.doses),0,dex.doses) # Set NA values to 0
)
Read in cefepime data
Show code
cefepime = read_excel(path = "/Users/aportugu/Desktop/CD19 project/EMR data/meds/2023.12.13.cefepime.xlsx")
cefepime$date = ymd(cefepime$date)
cefepime.df <- cefepime %>%
select(uwid, date, day, Dose) %>%
group_by(uwid) %>%
filter(day >=0) %>%
summarise(cefepime.first.day = min(day, na.rm=TRUE), cefepime.first.date = min(date, na.rm=TRUE), cefepime.last.day = max(day, na.rm=TRUE), cefepime.last.date = max(date, na.rm=TRUE), cefepime.doses = n())
dataset <- # join pre-LD CBC lab values
left_join(
x = dataset,
y = cefepime.df,
by = "uwid"
) %>%
mutate(
cefepime.doses = ifelse(is.na(cefepime.doses),0,cefepime.doses) # Set NA values to 0
)
Read in vancomycin data
Show code
vancomycin = read_excel(path = "/Users/aportugu/Desktop/CD19 project/EMR data/meds/2023.12.13.vancomycin.xlsx")
vancomycin$date = ymd(vancomycin$date)
vancomycin.df <- vancomycin %>%
select(uwid, date, day, Dose) %>%
group_by(uwid) %>%
filter(day >=0) %>%
summarise(vancomycin.first.day = min(day, na.rm=TRUE), vancomycin.first.date = min(date, na.rm=TRUE), vancomycin.last.day = max(day, na.rm=TRUE), vancomycin.last.date = max(date, na.rm=TRUE), vancomycin.doses = n())
dataset <- # join pre-LD CBC lab values
left_join(
x = dataset,
y = vancomycin.df,
by = "uwid"
) %>%
mutate(
vancomycin.doses = ifelse(is.na(vancomycin.doses),0,vancomycin.doses) # Set NA values to 0
)
Read in norepinephrine data
Show code
norepinephrine = read_excel(path = "/Users/aportugu/Desktop/CD19 project/EMR data/meds/2023.12.13.norepinephrine.xlsx")
norepinephrine$date = ymd(norepinephrine$date)
norepinephrine.df <- norepinephrine %>%
select(uwid, date, day, Dose) %>%
group_by(uwid) %>%
filter(day >=0) %>%
summarise(norepinephrine.first.day = min(day, na.rm=TRUE), norepinephrine.first.date = min(date, na.rm=TRUE), norepinephrine.last.day = max(day, na.rm=TRUE), norepinephrine.last.date = max(date, na.rm=TRUE), norepinephrine.doses = n())
dataset <- # join pre-LD CBC lab values
left_join(
x = dataset,
y = norepinephrine.df,
by = "uwid"
) %>%
mutate(
norepinephrine.doses = ifelse(is.na(norepinephrine.doses),0,norepinephrine.doses) # Set NA values to 0
)
Read in temp data
Show code
temperature = read_excel(path = "/Users/aportugu/Desktop/CD19 project/EMR data/vs/2023.12.13.temperature.xlsx")
temperature$date = ymd(temperature$date)
fever.df <- temperature %>%
select(uwid, date, day, temp_C) %>%
group_by(uwid) %>%
filter(day >=0 & temp_C >=38) %>%
summarise(fever.first.day = min(day, na.rm=TRUE), fever.first.date = min(date, na.rm=TRUE), fever.last.day = max(day, na.rm=TRUE), fever.last.date = max(date, na.rm=TRUE), fever.days = n_distinct(day))
dataset <- # join pre-LD CBC lab values
left_join(
x = dataset,
y = fever.df,
by = "uwid"
)
Read in ICE score data
Show code
ICE = read_excel(path = "/Users/aportugu/Desktop/CD19 project/EMR data/vs/2023.12.13.ICEscores.xlsx")
ICE$date = ymd(ICE$date)
ICE.df <- ICE %>%
select(uwid, date, day, ICE.SCORE, ICE.ATTENTION, ICE.FOLLOW.COMMANDS, ICE.NAME.OBJECTS, ICE.ORIENTATION, ICE.WRITING) %>%
group_by(uwid) %>%
filter(day >=0) %>%
summarise(ICE.min = min(ICE.SCORE, na.rm=TRUE), ICE.attention.min = min(ICE.ATTENTION, na.rm=TRUE), ICE.follow.commands.min = min(ICE.FOLLOW.COMMANDS, na.rm=TRUE), ICE.name.objects.min = min(ICE.NAME.OBJECTS, na.rm=TRUE), ICE.orientation.min = min(ICE.ORIENTATION, na.rm=TRUE), ICE.writing.min = min(ICE.WRITING, na.rm=TRUE))
dataset <- # join pre-LD CBC lab values
left_join(
x = dataset,
y = ICE.df,
by = "uwid"
)
ICE.less.than.10.df <- ICE %>%
select(uwid, date, day, ICE.SCORE, ICE.ATTENTION, ICE.FOLLOW.COMMANDS, ICE.NAME.OBJECTS, ICE.ORIENTATION, ICE.WRITING) %>%
group_by(uwid) %>%
filter(day >=0 & ICE.SCORE <10) %>%
summarise(ICE.less.than.10 = n_distinct(day))
dataset <- # join pre-LD CBC lab values
left_join(
x = dataset,
y = ICE.less.than.10.df,
by = "uwid"
)
All BP data points
Show code
BPdata = filter(BP, day >=-15 ) %>%
select(day, SBP, DBP, time, uwid) %>%
mutate(
time.percent = sapply( strsplit(time,":"),
function(x) {
x <- as.numeric(x)
x[1]/24
}
),
day = ifelse(day>=0, day + time.percent, day - time.percent),
MAP = SBP/3 + DBP * 2/3
)
BPdata <- # join pre-LD CBC lab values
left_join(
x = BPdata,
y = dataset %>%
select(CAR.T.Product.Type, uwid, Study.No, CRS.grade, ICANS.grade),
by = "uwid"
)
All ANC data points
Show code
CBCdata = filter(CBC, day >=-15 ) %>%
select(day, ancx, lymx, HgbAmt, TotPlateletCnt, time, uwid) %>%
mutate(
time.percent = sapply( strsplit(time,":"),
function(x) {
x <- as.numeric(x)
x[1]/24
}
),
day = ifelse(day>=0, day + time.percent, day - time.percent),
)
CBCdata <-
left_join(
x = CBCdata,
y = dataset %>%
select(CAR.T.Product.Type, uwid, Study.No),
by = "uwid"
)
Propensity scores
Regression analysis for treatment allocation
Show code
variables <- c("CAR.T.Product.Type", "Age", "Second.line", "LDH.preLD", "ALC.preLD", "ASCT", "Largest.lesion", "tDLBCL", "ECOG.status", "Extranodal", "Bridging.response.category")
data1 <- dataset %>%
drop_na(LDH.preLD, ALC.preLD, Bridging.response.category, ECOG) %>%
mutate(
Bulky = ifelse(Largest.lesion >=5,1,0),
ECOG.status = ifelse(ECOG >=2,1,0),
ALC.low = ifelse(ALC.preLD <=1,1,0),
CAR.T.Product.Type = recode(CAR.T.Product.Type, "Breyanzi" = 1, "Yescarta" = 0),
Bridging.response.category = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD", "3"="Unknown response"), levels = c("No bridging","CR/PR","SD/PD", "Unknown response")),
)
uv_tab <- tbl_uvregression(
data1[c(variables)],
method = glm,
y = CAR.T.Product.Type,
method.args = list(family = binomial),
exponentiate = TRUE
) %>%
sort_p()
mv_tab<-glm(CAR.T.Product.Type ~ Age + Second.line + LDH.preLD + ALC.preLD + ASCT + Largest.lesion + tDLBCL + ECOG.status + Extranodal + Bridging.response.category, data=data1, family=binomial) %>%
tbl_regression(exponentiate=TRUE)
tbl_merge(list(uv_tab, mv_tab), tab_spanner = c("**Univariate**", "**Multivariable**"))
| Characteristic |
Univariate
|
Multivariable
|
| N |
OR |
95% CI |
p-value |
OR |
95% CI |
p-value |
| Age |
148 |
1.06 |
1.03, 1.10 |
<0.001 |
1.06 |
1.03, 1.11 |
0.001 |
| Bridging.response.category |
148 |
|
|
|
|
|
|
| No bridging |
|
— |
— |
|
— |
— |
|
| CR/PR |
|
3.30 |
1.23, 8.98 |
0.017 |
2.64 |
0.83, 8.46 |
0.10 |
| SD/PD |
|
1.77 |
0.76, 4.09 |
0.2 |
2.84 |
0.96, 8.80 |
0.062 |
| Unknown response |
|
46,954,082 |
0.00, NA |
>0.9 |
38,025,973 |
0.00, NA |
>0.9 |
| Second.line |
148 |
2.48 |
0.84, 7.50 |
0.10 |
1.95 |
0.51, 7.74 |
0.3 |
| ASCT |
148 |
0.46 |
0.15, 1.24 |
0.15 |
0.50 |
0.14, 1.49 |
0.2 |
| ALC.preLD |
148 |
1.41 |
1.00, 2.41 |
0.2 |
1.24 |
0.96, 2.24 |
0.3 |
| tDLBCL |
148 |
1.56 |
0.68, 3.51 |
0.3 |
1.70 |
0.61, 4.66 |
0.3 |
| LDH.preLD |
148 |
1.00 |
1.00, 1.00 |
0.3 |
1.00 |
1.00, 1.00 |
0.3 |
| Largest.lesion |
148 |
0.95 |
0.85, 1.05 |
0.3 |
0.93 |
0.81, 1.06 |
0.3 |
| ECOG.status |
148 |
0.74 |
0.29, 1.78 |
0.5 |
0.74 |
0.23, 2.16 |
0.6 |
| Extranodal |
148 |
0.88 |
0.44, 1.76 |
0.7 |
1.11 |
0.47, 2.68 |
0.8 |
IPTW
Show code
IPTW.data <- dataset %>%
#drop_na(LDH.preLD, ALC.preLD, Bridging.response.category, ECOG) %>%
mutate(
Age.65 = ifelse(Age >=65,1,0),
Male.sex = ifelse(Sex == "M",1,0),
Bulky = ifelse(Largest.lesion >=5,1,0),
ECOG.status = ifelse(ECOG >=2,1,0)
)
## Use the WeightIt function to generate propensity scores and weights
W.out <- weightit(CAR.T.Product.Type ~ Age + Second.line + ASCT + Largest.lesion + tDLBCL + ECOG.status + Extranodal,
data=IPTW.data,
method = "glm",
estimand = "ATE",
stabilize = TRUE)
summary = summary(W.out)
bal.tab(W.out, stats = c("m", "v"), thresholds = c(m=0.25), binary = "std")
Balance Measures
Type Diff.Adj M.Threshold V.Ratio.Adj
prop.score Distance 0.0848 Balanced, <0.25 1.2909
Age Contin. -0.1721 Balanced, <0.25 1.5656
Second.line Binary 0.0487 Balanced, <0.25 .
ASCT Binary 0.0734 Balanced, <0.25 .
Largest.lesion Contin. -0.0718 Balanced, <0.25 0.3979
tDLBCL Binary -0.0855 Balanced, <0.25 .
ECOG.status Binary -0.0856 Balanced, <0.25 .
Extranodal Binary -0.0411 Balanced, <0.25 .
Balance tally for mean differences
count
Balanced, <0.25 8
Not Balanced, >0.25 0
Variable with the greatest mean difference
Variable Diff.Adj M.Threshold
Age -0.1721 Balanced, <0.25
Effective sample sizes
Breyanzi Yescarta
Unadjusted 50. 99.
Adjusted 40.48 86.18
Show code
love.plot(W.out,
binary = "std",
line = TRUE,
abs = TRUE,
thresholds = c(m=0.25),
var.order = "unadjusted",
var.names = c(
Age = "Age",
prop.score = "Distance",
Male.sex = "Male sex",
Second.line = "Second line",
LDH.preLD = "LDH pre-LD",
ALC.preLD = "ALC pre-LD",
Bridging = "Bridging",
ASCT = "Prior ASCT",
Largest.lesion = "Largest lesion",
Bridging.response.category = "Bridging response",
tDLBCL = "tDLBCL vs other",
ECOG.status = "ECOG\u22652"
))
Show code
IPTW.data$weights <- W.out$weights * (summary$effective.sample.size$Breyanzi[2] + summary$effective.sample.size$Yescarta[2])/sum(W.out$weights) # Attach normalized weights to a dataset
IPTW.data$ps <- W.out$ps
PSM
Show code
PSM.data <- dataset %>%
#drop_na(LDH.preLD, ALC.preLD, Bridging.response.category, ECOG) %>%
mutate(
Age.65 = ifelse(Age >=65,1,0),
Male.sex = ifelse(Sex == "M",1,0),
Bulky = ifelse(Largest.lesion >=5,1,0),
ECOG.status = ifelse(ECOG >=2,1,0),
Bridging.response.category = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD", "3"="Unknown response"), levels = c("No bridging","CR/PR","SD/PD", "Unknown response")),
ALC.low = ifelse(ALC.preLD <=1,1,0),
CAR.T.Product.Type = ifelse(CAR.T.Product.Type == "Breyanzi",1,0)
)
m.out <- matchit(CAR.T.Product.Type ~ Age + Second.line + ASCT + Largest.lesion + tDLBCL + ECOG.status + Extranodal, data=PSM.data, method = "full", distance = "glm", link = "logit") # Full matching
bal.tab(m.out, stats = c("m", "v"), thresholds = c(m=0.25), binary = "std")
Balance Measures
Type Diff.Adj M.Threshold V.Ratio.Adj
distance Distance -0.0027 Balanced, <0.25 0.9453
Age Contin. -0.0776 Balanced, <0.25 1.1420
Second.line Binary 0.1300 Balanced, <0.25 .
ASCT Binary -0.0300 Balanced, <0.25 .
Largest.lesion Contin. -0.0545 Balanced, <0.25 2.5635
tDLBCL Binary 0.0027 Balanced, <0.25 .
ECOG.status Binary -0.0591 Balanced, <0.25 .
Extranodal Binary -0.2025 Balanced, <0.25 .
Balance tally for mean differences
count
Balanced, <0.25 8
Not Balanced, >0.25 0
Variable with the greatest mean difference
Variable Diff.Adj M.Threshold
Extranodal -0.2025 Balanced, <0.25
Sample sizes
Control Treated
All 99. 50
Matched (ESS) 26.27 50
Matched (Unweighted) 99. 50
Show code
m.out_NN <- matchit(CAR.T.Product.Type ~ Age + Second.line + ASCT + Largest.lesion + tDLBCL + ECOG.status + Extranodal, data=PSM.data, method = "nearest", distance = "glm", link = "logit") # Nearest neighbor matching for comparison
love.plot(m.out, stats = c("m"), abs = TRUE,
binary = "std",
drop.distance = FALSE,
weights = list(nn = m.out_NN),
var.order = "unadjusted",
line = TRUE,
thresholds = c(m=0.25, ks = 0.05),
sample.names = c("Original", "Full Matching", "Nearest Neighbor Matching"),
position = "bottom",
var.names = c(
prop.score = "Distance",
Bridging = "Bridging",
LDH.preLD = "LDH pre-LD",
LDH.status = "LDH status",
ALC.preLD = "ALC pre-LD",
Age.62 = "Age \u226562",
Male.sex = "Male sex",
Second.line = "Second line",
ASCT = "Prior ASCT",
Largest.lesion = "Largest lesion",
HCT.CI = "HCT-CI",
ECOG.status = "ECOG \u22652",
Bridging.response.category = "Bridging response",
tDLBCL = "tDLBCL vs other"
)
)
Show code
# Create a dataset with PSM weights using full matching
m.data <- match.data(m.out) %>%
mutate(
CAR.T.Product.Type = ifelse(CAR.T.Product.Type == 1, "Breyanzi","Yescarta")
)
m.data_NN <- match.data(m.out_NN)
Scatterplot of weights
Show code
ggplot(IPTW.data %>% mutate(Product = CAR.T.Product.Type, Product = recode(Product, "Breyanzi"="Liso-cel","Yescarta"="Axi-cel")), aes(x=ps, y = weights, color = Product)) +
geom_point(shape = 16) +
theme_classic() +
labs(x = "Propensity score", y = "Weights") # Add a legend label
Show code

TABLES
Baseline characteristics
Show code
theme_gtsummary_compact()
dataset %>%
transmute(
#"Age \u226565 years" = ifelse(Age >=65,1,0),
"Age (years)" = Age,
"Male sex" = ifelse(Sex == "M", "Yes","No"),
"ECOG PS" = factor( recode(ECOG, "0"="0-1","1"="0-1","2"="\u22652","3"="\u22652","4"="\u22652"), levels = c("0-1", "\u22652") ),
"HCT-CI" = HCT.CI,
"TRANSCEND eligible" = TRANSCEND,
"Second line" = Second.line,
"Prior ASCT" = ASCT,
#"Received bridging" = Bridging,
"Bridging response category" = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD", "3" = "Unknown response"), levels = c("No bridging","CR/PR","SD/PD", "Unknown response")),
"Disease subtype" = Disease,
"LDH" = LDH.preLD,
"ALC" = ALC.preLD,
#"Elevated LDH (\u2265210 U/L)" = ifelse(LDH.preLD >=210,"Yes","No"),
#"LDH status" = factor(recode(LDH.status, "0" = "\u2264ULN", "1" = "[ULN; 2x ULN]", "2"=">2x ULN"), levels = c("\u2264ULN", "[ULN; 2x ULN]", ">2x ULN") ),
"Largest lesion (cm)" = Largest.lesion,
#"Bulky (\u22655 cm)" = ifelse(Bulky == 1, "Yes","No"),
"Extranodal" = ifelse(Extranodal == 1, "Yes","No"),
"Out-of-spec" = ifelse(EAP == 1,"Yes","No"),
"Product" = factor(recode(CAR.T.Product.Type, "Breyanzi"= "Liso-cel", "Yescarta" = "Axi-cel"), levels = c("Liso-cel","Axi-cel"))
) %>%
tbl_summary(
missing = "ifany",
#sort = all_categorical() ~ "frequency",
type = c("HCT-CI" = "continuous", "ECOG" = "continuous"),
#type = c("HCT-CI" = "continuous", "ECOG" = "continuous", "Max CRS grade" = "continuous", "Max ICANS grade" = "continuous", "Total inpatient duration (days)" = "continuous", "Days with fever" ~ "continuous"),
statistic = list(
all_continuous() ~ "{median} ({p25}, {p75})",
all_categorical() ~ "{n} ({p}%)",
"Age (years)" ~"{median} ({min} to {max})"
#"Total inpatient duration (days)" ~ "{median} ({min} to {max})"
#"HCT-CI" ~ "{median} ({min} to {max})"
)
) %>%
bold_labels
| Characteristic |
N = 149 |
| Age (years) |
62 (26 to 83) |
| Male sex |
93 (62%) |
| ECOG PS |
|
| 0-1 |
120 (81%) |
| ≥2 |
29 (19%) |
| HCT-CI |
1.00 (1.00, 3.00) |
| TRANSCEND eligible |
102 (68%) |
| Second line |
15 (10%) |
| Prior ASCT |
24 (16%) |
| Bridging response category |
|
| No bridging |
88 (59%) |
| CR/PR |
21 (14%) |
| SD/PD |
36 (24%) |
| Unknown response |
4 (2.7%) |
| Disease subtype |
|
| DLBCL |
104 (70%) |
| HGBCL |
7 (4.7%) |
| PMBCL |
5 (3.4%) |
| TCHRLBCL |
2 (1.3%) |
| tDLBCL |
31 (21%) |
| LDH |
186 (151, 292) |
| Unknown |
1 |
| ALC |
0.60 (0.33, 0.99) |
| Largest lesion (cm) |
3.2 (1.6, 5.5) |
| Extranodal |
87 (58%) |
| Out-of-spec |
13 (8.7%) |
| Product |
|
| Liso-cel |
50 (34%) |
| Axi-cel |
99 (66%) |
Show code
dataset %>%
transmute(
#"Age \u226565 years" = ifelse(Age >=65,1,0),
"Age (years)" = Age,
"Male sex" = ifelse(Sex == "M", "Yes","No"),
"ECOG PS" = factor( recode(ECOG, "0"="0-1","1"="0-1","2"="\u22652","3"="\u22652","4"="\u22652"), levels = c("0-1", "\u22652") ),
"HCT-CI" = HCT.CI,
"TRANSCEND eligible" = TRANSCEND,
"Second line" = Second.line,
"Prior ASCT" = ASCT,
#"Received bridging" = Bridging,
"Bridging response category" = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD", "3" = "Unknown response"), levels = c("No bridging","CR/PR","SD/PD", "Unknown response")),
"Disease subtype" = Disease,
"LDH" = LDH.preLD,
"ALC" = ALC.preLD,
#"Elevated LDH (\u2265210 U/L)" = ifelse(LDH.preLD >=210,"Yes","No"),
#"LDH status" = factor(recode(LDH.status, "0" = "\u2264ULN", "1" = "[ULN; 2x ULN]", "2"=">2x ULN"), levels = c("\u2264ULN", "[ULN; 2x ULN]", ">2x ULN") ),
"Largest lesion (cm)" = Largest.lesion,
#"Bulky (\u22655 cm)" = ifelse(Bulky == 1, "Yes","No"),
"Extranodal" = ifelse(Extranodal == 1, "Yes","No"),
"Out-of-specification" = ifelse(EAP == 1,"Yes","No"),
"Product" = factor(recode(CAR.T.Product.Type, "Breyanzi"= "Liso-cel", "Yescarta" = "Axi-cel"), levels = c("Liso-cel","Axi-cel"))
) %>%
tbl_summary(
by = "Product",
missing = "ifany",
#sort = all_categorical() ~ "frequency",
type = c("HCT-CI" = "continuous", "ECOG" = "continuous"),
statistic = list(
all_continuous() ~ "{median} ({p25}, {p75})",
all_categorical() ~ "{n} ({p}%)",
"Age (years)" ~"{median} ({min} to {max})"
)
) %>%
modify_spanning_header(all_stat_cols() ~ "**CAR-T Treatment**") %>%
modify_header(all_stat_cols() ~ "**{level}**<br>N = {n} ({style_percent(p)}%)") %>%
bold_labels %>%
add_p() %>%
add_stat_label()
| Characteristic |
CAR-T Treatment
|
p-value |
Liso-cel N = 50 (34%) |
Axi-cel N = 99 (66%) |
| Age (years), Median (Range) |
67 (45 to 83) |
61 (26 to 79) |
<0.001 |
| Male sex, n (%) |
27 (54%) |
66 (67%) |
0.13 |
| ECOG PS, n (%) |
|
|
0.4 |
| 0-1 |
42 (84%) |
78 (79%) |
|
| ≥2 |
8 (16%) |
21 (21%) |
|
| HCT-CI, Median (IQR) |
1.00 (1.00, 3.00) |
1.00 (1.00, 3.00) |
>0.9 |
| TRANSCEND eligible, n (%) |
31 (62%) |
71 (72%) |
0.2 |
| Second line, n (%) |
8 (16%) |
7 (7.1%) |
0.087 |
| Prior ASCT, n (%) |
5 (10%) |
19 (19%) |
0.15 |
| Bridging response category, n (%) |
|
|
0.002 |
| No bridging |
22 (44%) |
66 (67%) |
|
| CR/PR |
11 (22%) |
10 (10%) |
|
| SD/PD |
13 (26%) |
23 (23%) |
|
| Unknown response |
4 (8.0%) |
0 (0%) |
|
| Disease subtype, n (%) |
|
|
0.4 |
| DLBCL |
33 (66%) |
71 (72%) |
|
| HGBCL |
3 (6.0%) |
4 (4.0%) |
|
| PMBCL |
0 (0%) |
5 (5.1%) |
|
| TCHRLBCL |
1 (2.0%) |
1 (1.0%) |
|
| tDLBCL |
13 (26%) |
18 (18%) |
|
| LDH, Median (IQR) |
180 (151, 245) |
206 (153, 308) |
0.3 |
| Unknown |
0 |
1 |
|
| ALC, Median (IQR) |
0.74 (0.44, 1.01) |
0.57 (0.31, 0.96) |
0.081 |
| Largest lesion (cm), Median (IQR) |
2.7 (0.2, 4.4) |
3.4 (2.1, 6.6) |
0.067 |
| Extranodal, n (%) |
28 (56%) |
59 (60%) |
0.7 |
| Out-of-specification, n (%) |
11 (22%) |
2 (2.0%) |
<0.001 |
IPTW weighted data table
Show code
theme_gtsummary_compact()
data1 = IPTW.data %>%
mutate(
"Age (years)" = Age,
Male.sex = ifelse(Sex == "M", "Yes","No"),
ECOG = factor( recode(ECOG, "0"="0-1","1"="0-1","2"="\u22652","3"="\u22652","4"="\u22652"), levels = c("0-1", "\u22652") ),
Bridging = factor(recode(Bridging.response.category, "0"="No bridging","1"="CR/PR","2"="SD/PD","3"="Unknown response"), levels = c("No bridging","CR/PR","SD/PD", "Unknown response")),
Product = factor(recode(CAR.T.Product.Type, "Breyanzi"= "Liso-cel", "Yescarta" = "Axi-cel"), levels = c("Liso-cel","Axi-cel")),
)
survey::svydesign(
id = ~0,
weights = ~weights,
data = data1,
fpc = NULL
) %>%
tbl_svysummary(
by = Product,
missing = "ifany",
statistic = list(
all_continuous() ~ "{median} ({p25}, {p75})",
all_categorical() ~ "{n} ({p}%)"),
include = c(Age, Male.sex, ECOG, HCT.CI, TRANSCEND, Second.line, ASCT, Disease, LDH.preLD, ALC.preLD, Largest.lesion, Extranodal, Bridging, EAP),
label = list(
Male.sex ~ "Male sex",
HCT.CI ~ "HCT-CI",
Second.line ~ "Second line",
LDH.preLD ~ "LDH",
ALC.preLD ~ "ALC",
Largest.lesion ~ "Largest lesion (cm)",
Bridging ~ "Bridging response category"
),
) %>%
add_p() %>%
bold_labels()#%>%
| Characteristic |
Liso-cel, N = 41 |
Axi-cel, N = 86 |
p-value |
| Age |
61 (52, 69) |
64 (52, 68) |
0.7 |
| Male sex |
24 (59%) |
59 (69%) |
0.3 |
| ECOG |
|
|
0.7 |
| 0-1 |
31 (76%) |
68 (79%) |
|
| ≥2 |
10 (24%) |
18 (21%) |
|
| HCT-CI |
1.00 (1.00, 3.00) |
1.00 (1.00, 3.00) |
0.9 |
| TRANSCEND |
22 (55%) |
63 (73%) |
0.053 |
| Second line |
4 (8.7%) |
9 (10%) |
0.8 |
| ASCT |
5 (13%) |
13 (16%) |
0.7 |
| Disease |
|
|
0.7 |
| DLBCL |
27 (67%) |
59 (69%) |
|
| HGBCL |
2 (4.2%) |
3 (3.2%) |
|
| PMBCL |
0 (0%) |
3 (3.6%) |
|
| TCHRLBCL |
1 (1.8%) |
1 (1.0%) |
|
| tDLBCL |
11 (27%) |
20 (23%) |
|
| LDH |
180 (151, 266) |
190 (147, 297) |
0.8 |
| Unknown |
0 |
1 |
|
| ALC |
0.56 (0.38, 0.91) |
0.54 (0.31, 0.97) |
0.5 |
| Largest lesion (cm) |
3.3 (0.0, 5.2) |
3.4 (2.1, 5.9) |
0.5 |
| Extranodal |
25 (61%) |
51 (59%) |
0.8 |
| Bridging response category |
|
|
0.020 |
| No bridging |
17 (42%) |
55 (64%) |
|
| CR/PR |
8 (19%) |
12 (14%) |
|
| SD/PD |
12 (30%) |
18 (21%) |
|
| Unknown response |
3 (7.9%) |
0 (0%) |
|
| EAP |
9 (23%) |
1 (1.6%) |
<0.001 |
Show code
Reasons ineligible for TRANSCEND
Show code
data <- dataset %>%
distinct() %>%
filter(TRANSCEND == 0 & !is.na(Rationale.category) ) %>%
count(Rationale.category) %>%
mutate(
pct = prop.table(n) * 100
)
data %>%
ggplot() +
aes(x = "", y = pct, fill = reorder(Rationale.category, -pct)) +
geom_col(position = 'stack', width = 1) +
coord_polar("y") +
xlab(NULL) +
ylab(NULL) +
theme_void() +
scale_fill_brewer(palette = "Pastel2") +
geom_text(aes(x = 1.3, label = paste0(sprintf("%1.f", pct), "%", "\u000A", "n=", n)), position = position_stack(vjust = 0.5), size = 5) +
theme(axis.text.x = element_blank(),
axis.ticks = element_blank(),
legend.text = element_text(size = 16),
legend.title = element_text(size = 16)) + # Set legend title font size and make it bold
labs(fill = paste0("Primary reason (N = ", tally(filter(dataset, TRANSCEND==0))$n, ")" ) )

Time to product infusion
Show code
theme_gtsummary_compact()
dataset %>%
#filter(Largest.lesion !=0) %>% #only include measurable disease
filter(Infused == 1) %>%
transmute(
"Product" = factor(recode(CAR.T.Product.Type, "Breyanzi"= "Liso-cel", "Yescarta" = "Axi-cel"), levels = c("Liso-cel","Axi-cel")),
"Vein-to-vein time (days)" = Vein.to.vein.time,
"Arrival-to-infusion time (days)" = Arrival.to.vein.time,
"Order-to-infusion time (days)" = Order.to.vein.time,
#"Total inpatient duration (days)" = inpatient.duration,
) %>%
tbl_summary(
by = "Product",
missing = "no",
statistic = list(
all_continuous() ~ "{median} ({p25}, {p75})",
all_categorical() ~ "{n} ({p}%)"
)
) %>%
bold_labels %>%
add_p() %>%
add_stat_label()
| Characteristic |
Liso-cel, N = 50 |
Axi-cel, N = 99 |
p-value |
| Vein-to-vein time (days), Median (IQR) |
34 (32, 40) |
27 (26, 30) |
<0.001 |
| Arrival-to-infusion time (days), Median (IQR) |
46 (42, 56) |
40 (35, 45) |
<0.001 |
| Order-to-infusion time (days), Median (IQR) |
62 (44, 77) |
34 (32, 41) |
<0.001 |
Pre-LD lab values
Show code
theme_gtsummary_compact()
dataset %>%
filter(LD == 1) %>%
transmute(
"Pre-LD WBC (10\U00B3/\U00B5L)" = WBC.preLD,
"Pre-LD Plt (10\U00B3/\U00B5L)" = Plt.preLD,
"Pre-LD Hgb (g/dL)" = Hgb.preLD,
"Pre-LD ANC (10\U00B3/\U00B5L)" = ANC.preLD,
"ALC pre-LD (10\U00B3/\U00B5L)" = ALC.preLD,
"Pre-LD ferritin (ng/mL)" = ferritin.preLD,
"Pre-LD cre (mg/dL)" = cre.preLD,
"LDH pre-LD (U/L)" = LDH.preLD,
"Product" = CAR.T.Product.Type,
) %>%
tbl_summary(
by = "Product",
missing = "no",
#sort = all_categorical() ~ "frequency",
statistic = list(
all_continuous() ~ "{median} ({p25}, {p75})",
all_categorical() ~ "{n} ({p}%)"
)
) %>%
bold_labels %>%
add_p() %>%
sort_p() %>%
add_stat_label()
| Characteristic |
Breyanzi, N = 50 |
Yescarta, N = 99 |
p-value |
| ALC pre-LD (10³/µL), Median (IQR) |
0.74 (0.44, 1.01) |
0.57 (0.31, 0.96) |
0.081 |
| Pre-LD Hgb (g/dL), Median (IQR) |
11.30 (10.05, 12.32) |
10.20 (9.60, 11.90) |
0.10 |
| LDH pre-LD (U/L), Median (IQR) |
180 (151, 245) |
206 (153, 308) |
0.3 |
| Pre-LD ferritin (ng/mL), Median (IQR) |
266 (119, 672) |
388 (174, 836) |
0.4 |
| Pre-LD cre (mg/dL), Median (IQR) |
0.84 (0.66, 1.01) |
0.87 (0.70, 1.04) |
0.6 |
| Pre-LD ANC (10³/µL), Median (IQR) |
2.67 (2.06, 4.21) |
3.00 (1.61, 4.97) |
0.6 |
| Pre-LD Plt (10³/µL), Median (IQR) |
149 (114, 199) |
160 (99, 203) |
0.8 |
| Pre-LD WBC (10³/µL), Median (IQR) |
4.2 (3.4, 6.3) |
4.7 (3.0, 6.6) |
>0.9 |
Admission characteristics
Show code
theme_gtsummary_compact()
dataset %>%
filter(Infused == 1) %>%
transmute(
"Product" = CAR.T.Product.Type,
"Vein-to-vein time (days)" = Vein.to.vein.time,
"Order-to-vein time (days)" = Order.to.vein.time,
"Arrival-to-vein time (days)" = Arrival.to.vein.time,
"# of admissions" = admissions,
'2+ admissions' = ifelse(admissions>=2, 1, 0),
"Elective admission" = recode(elective.admission, "1" = "Yes", "0" = "No"),
"Total inpatient duration (days)" = inpatient.duration,
"Elective duration (days)" = elective.duration,
"Non-elective duration (days)" = inpatient.duration - elective.duration,
) %>%
tbl_summary(
by = "Product",
missing = "no",
#sort = all_categorical() ~ "frequency",
type = c("Elective duration (days)" ~ "continuous"),
statistic = list(
all_continuous() ~ "{median} ({p25}, {p75})",
all_categorical() ~ "{n} ({p}%)",
"Elective duration (days)" ~ "{median} ({min} to {max})",
"Non-elective duration (days)" ~ "{median} ({min} to {max})",
"Total inpatient duration (days)" ~ "{median} ({min} to {max})"
)
) %>%
bold_labels %>%
add_p() %>%
add_stat_label()
| Characteristic |
Breyanzi, N = 50 |
Yescarta, N = 99 |
p-value |
| Vein-to-vein time (days), Median (IQR) |
34 (32, 40) |
27 (26, 30) |
<0.001 |
| Order-to-vein time (days), Median (IQR) |
62 (44, 77) |
34 (32, 41) |
<0.001 |
| Arrival-to-vein time (days), Median (IQR) |
46 (42, 56) |
40 (35, 45) |
<0.001 |
| # of admissions, n (%) |
|
|
<0.001 |
| 0 |
19 (38%) |
9 (9.1%) |
|
| 1 |
27 (54%) |
69 (70%) |
|
| 2 |
2 (4.0%) |
18 (18%) |
|
| 3 |
2 (4.0%) |
3 (3.0%) |
|
| 2+ admissions, n (%) |
4 (8.0%) |
21 (21%) |
0.042 |
| Elective admission, n (%) |
5 (10%) |
82 (83%) |
<0.001 |
| Total inpatient duration (days), Median (Range) |
5 (0 to 35) |
14 (0 to 54) |
<0.001 |
| Elective duration (days), Median (Range) |
0 (0 to 30) |
12 (0 to 48) |
<0.001 |
| Non-elective duration (days), Median (Range) |
2.5 (0.0 to 35.0) |
0.0 (0.0 to 54.0) |
0.006 |
Vein-to-vein histogram
Show code
Median_breyanzi_vv = signif(median(as.numeric(filter(dataset, CAR.T.Product.Type == "Breyanzi")$Vein.to.vein.time)), 2)
Median_yescarta_vv = signif(median(as.numeric(filter(dataset, CAR.T.Product.Type == "Yescarta")$Vein.to.vein.time)), 2)
histogram_vv <- dataset %>%
mutate(CAR.T.Product.Type = recode(CAR.T.Product.Type,"Breyanzi" = "Liso-cel","Yescarta" = "Axi-cel")) %>%
ggplot( aes(x=as.numeric(Vein.to.vein.time), fill=CAR.T.Product.Type) ) +
geom_histogram( color="#e9ecef", alpha=0.6, position = 'identity', binwidth=7) +
scale_fill_manual(values = c("#69b3a2", "#404080"), guide = "none") + # Remove the legend
theme_classic() +
labs(fill="") +
geom_vline(aes(xintercept = Median_yescarta_vv),
linetype = "dashed", color = "#69b3a2", linewidth = 0.75)+
geom_vline(aes(xintercept = Median_breyanzi_vv),
linetype = "dashed", color = "#404080", linewidth = 0.75) +
xlim(10, 70)+
xlab("Vein-to-vein time (days)") +
ylab("Number of patients") +
annotate("text", label=Median_yescarta_vv, x = Median_yescarta_vv +3, y = 61, color = "#69b3a2") +
annotate("text", label=Median_breyanzi_vv, x = Median_breyanzi_vv +3, y = 61, color = "#404080") +
theme(legend.position = c(0.8, 0.8)) +
theme(
axis.title = element_text(size = 16),
axis.text = element_text(size = 16),
legend.title = element_text(size = 16),
legend.text = element_text(size = 14)
) +
annotate("text", x = 45, y = 55, label = sprintf("p <.001"), size = 5)
histogram_vv

Age histogram
Show code
Median_breyanzi_age = signif(median(as.numeric(filter(dataset, CAR.T.Product.Type == "Breyanzi")$Age)), 2)
Median_yescarta_age = signif(median(as.numeric(filter(dataset, CAR.T.Product.Type == "Yescarta")$Age)), 2)
histogram_age <- dataset %>%
mutate(CAR.T.Product.Type = recode(CAR.T.Product.Type,"Breyanzi" = "Liso-cel","Yescarta" = "Axi-cel")) %>%
ggplot( aes(x=as.numeric(Age), fill=CAR.T.Product.Type) ) +
geom_histogram( color="#e9ecef", alpha=0.6, position = 'identity', binwidth=5) +
scale_fill_manual(values=c("#69b3a2", "#404080")) +
theme_classic() +
labs(fill="") +
geom_vline(aes(xintercept = Median_yescarta_age),
linetype = "dashed", color = "#69b3a2", linewidth = 0.75)+
geom_vline(aes(xintercept = Median_breyanzi_age),
linetype = "dashed", color = "#404080", linewidth = 0.75) +
xlim(20, 90)+
xlab("Age (years)") +
ylab("Number of patients") +
annotate("text", label=Median_yescarta_age, x = Median_yescarta_age +3, y = 22, color = "#69b3a2") +
annotate("text", label=Median_breyanzi_age, x = Median_breyanzi_age +3, y = 22, color = "#404080") +
theme(legend.position = c(0.87, 0.8)) +
theme(
axis.title = element_text(size = 16),
axis.text = element_text(size = 16),
legend.title = element_text(size = 16),
legend.text = element_text(size = 12)
) +
annotate("text", x = 50, y = 20, label = sprintf("p <.001"), size = 5)
histogram_age

Combined histogram
Show code
ggarrange(histogram_vv, histogram_age, ncol = 2, labels = c("A", "B"))

Table for response
Show code
theme_gtsummary_compact()
data1 <- dataset %>%
mutate(
CAR.T.Product.Type = recode(CAR.T.Product.Type, "Breyanzi" = "Liso-cel","Yescarta" = "Axi-cel")
)
tbl1 <- data1 %>%
filter(Infused == 1) %>%
filter(Response.evaluable ==1) %>% #only include measurable disease
transmute(
"Product" = CAR.T.Product.Type,
"Initial response" = Initial.response,
"Best response" = Best.response,
"Progressive disease" = recode(Best.PD,"0"="No","1"="Yes"),
"ORR" = ifelse(Best.response == "CR" | Best.response == "PR",1,0)
) %>%
tbl_summary(
by = "Product",
missing = "no",
#sort = all_categorical() ~ "frequency",
statistic = list(
all_continuous() ~ "{median} ({p25}, {p75})",
all_categorical() ~ "{n} ({p}%)"
)
) %>%
bold_labels %>%
add_p() %>%
add_stat_label()
tbl2 <- data1 %>%
filter(Infused == 1) %>%
transmute(
"Product" = CAR.T.Product.Type,
"Initial response" = Initial.response,
"Best response" = Best.response,
"Progressive disease" = recode(Best.PD,"0"="No","1"="Yes"),
"ORR" = ifelse(Best.response == "CR" | Best.response == "PR",1,0)
) %>%
tbl_summary(
by = "Product",
missing = "no",
#sort = all_categorical() ~ "frequency",
statistic = list(
all_continuous() ~ "{median} ({p25}, {p75})",
all_categorical() ~ "{n} ({p}%)"
)
) %>%
bold_labels %>%
add_p() %>%
add_stat_label()
tbl_merge(
tbls = list(tbl1, tbl2), # combine
tab_spanner = c("**Response evaluable**", "**All patients**")) # set header names
| Characteristic |
Response evaluable
|
All patients
|
| Axi-cel, N = 95 |
Liso-cel, N = 41 |
p-value |
Axi-cel, N = 99 |
Liso-cel, N = 50 |
p-value |
| Initial response, n (%) |
|
|
0.7 |
|
|
>0.9 |
| CR |
39 (41%) |
13 (32%) |
|
42 (42%) |
22 (44%) |
|
| PD |
21 (22%) |
10 (24%) |
|
22 (22%) |
10 (20%) |
|
| PR |
33 (35%) |
17 (41%) |
|
33 (33%) |
17 (34%) |
|
| SD |
2 (2.1%) |
1 (2.4%) |
|
2 (2.0%) |
1 (2.0%) |
|
| Best response, n (%) |
|
|
>0.9 |
|
|
0.7 |
| CR |
45 (47%) |
20 (49%) |
|
48 (48%) |
29 (58%) |
|
| PD |
21 (22%) |
10 (24%) |
|
22 (22%) |
10 (20%) |
|
| PR |
28 (29%) |
11 (27%) |
|
28 (28%) |
11 (22%) |
|
| SD |
1 (1.1%) |
0 (0%) |
|
1 (1.0%) |
0 (0%) |
|
| Progressive disease, n (%) |
21 (22%) |
10 (24%) |
0.8 |
22 (22%) |
10 (20%) |
0.8 |
| ORR, n (%) |
73 (77%) |
31 (76%) |
0.9 |
76 (77%) |
40 (80%) |
0.7 |
IPTW weighted response table
Show code
theme_gtsummary_compact()
data1 = IPTW.data %>%
transmute(
"Product" = recode(CAR.T.Product.Type, "Breyanzi"="Liso-cel","Yescarta"="Axi-cel"),
"Initial response" = Initial.response,
"Best response" = Best.response,
"Progressive disease" = as.factor( recode(Best.PD,"0"="No","1"="Yes") ),
"ORR" = ifelse(Best.response == "CR" | Best.response == "PR",1,0),
weights,
Response.evaluable
)
tbl1<- survey::svydesign(
id = ~0,
weights = ~weights,
data = filter(data1, Response.evaluable==1), # Only include measurable disease
fpc = NULL
) %>%
tbl_svysummary(
by = Product,
missing = "ifany",
statistic = list(
all_continuous() ~ "{median} ({p25}, {p75})",
all_categorical() ~ "{n} ({p}%)"),
include = c("Initial response", "Best response", "Progressive disease", "ORR")
) %>%
bold_labels() %>%
add_p()
tbl2<- survey::svydesign(
id = ~0,
weights = ~weights,
data = data1, # Include response evaluable and all patients
fpc = NULL
) %>%
tbl_svysummary(
by = Product,
missing = "ifany",
statistic = list(
all_continuous() ~ "{median} ({p25}, {p75})",
all_categorical() ~ "{n} ({p}%)"),
include = c("Initial response", "Best response", "Progressive disease", "ORR")
) %>%
bold_labels() %>%
add_p()
tbl_merge(
tbls = list(tbl1, tbl2), # combine
tab_spanner = c("**Response evaluable**", "**All patients**")) # set header names
| Characteristic |
Response evaluable
|
All patients
|
| Axi-cel, N = 82 |
Liso-cel, N = 34 |
p-value |
Axi-cel, N = 86 |
Liso-cel, N = 41 |
p-value |
| Initial response |
|
|
0.7 |
|
|
0.8 |
| CR |
36 (44%) |
12 (34%) |
|
38 (44%) |
18 (45%) |
|
| PD |
18 (22%) |
7 (21%) |
|
20 (24%) |
7 (17%) |
|
| PR |
26 (32%) |
14 (43%) |
|
26 (31%) |
14 (36%) |
|
| SD |
1 (1.8%) |
1 (2.8%) |
|
1 (1.7%) |
1 (2.4%) |
|
| Best response |
|
|
>0.9 |
|
|
0.6 |
| CR |
41 (50%) |
18 (52%) |
|
43 (50%) |
24 (60%) |
|
| PD |
18 (22%) |
7 (21%) |
|
20 (24%) |
7 (17%) |
|
| PR |
22 (27%) |
9 (27%) |
|
22 (26%) |
9 (23%) |
|
| SD |
1 (1.0%) |
0 (0%) |
|
1 (1.0%) |
0 (0%) |
|
| Progressive disease |
18 (22%) |
7 (21%) |
0.8 |
20 (24%) |
7 (17%) |
0.4 |
| ORR |
63 (77%) |
27 (79%) |
0.7 |
65 (75%) |
34 (83%) |
0.3 |
Table for toxicity
Show code
theme_gtsummary_compact()
dataset %>%
filter(Infused == 1) %>%
transmute(
"Product" = CAR.T.Product.Type,
#"Max CRS grade" = CRS.grade,
"CRS any grade" = ifelse( CRS.grade != 0, 1, 0),
"CRS grade 3-4" = ifelse( CRS.grade ==3 | CRS.grade == 4, 1, 0),
"Time to CRS (days)" = CRS.day,
#"Max ICANS grade" = ICANS.grade,
"ICANS any grade" = ifelse( ICANS.grade != 0,1,0),
"ICANS grade 3-4" = ifelse( ICANS.grade ==3 | ICANS.grade == 4,1,0),
"Days with fever" = fever.days,
"Fever 1st day" = fever.first.day,
"Time to ICANS (days)" = ICANS.day,
"Toci doses" = toci.doses,
"Received toci" = ifelse(toci.doses !=0,1,0),
"Dex doses" = dex.doses,
"Received dex" = ifelse(dex.doses !=0,1,0),
"ICE score min" = ICE.min
) %>%
tbl_summary(
by = "Product",
missing = "no",
#sort = all_categorical() ~ "frequency",
statistic = list(
all_continuous() ~ "{median} ({p25}, {p75})",
all_categorical() ~ "{n} ({p}%)"
#"Time to ICANS (days)" ~ "{median} ({min}, {max})"
),
type = list("Toci doses" ~ "continuous", "ICE score min" ~ "continuous", "Dex doses" ~ "continuous", "Time to ICANS (days)" ~ "continuous")
) %>%
bold_labels %>%
add_p() %>%
add_stat_label()
| Characteristic |
Breyanzi, N = 50 |
Yescarta, N = 99 |
p-value |
| CRS any grade, n (%) |
32 (64%) |
88 (89%) |
<0.001 |
| CRS grade 3-4, n (%) |
1 (2.0%) |
8 (8.1%) |
0.3 |
| Time to CRS (days), Median (IQR) |
4.00 (2.00, 6.00) |
4.00 (2.00, 6.00) |
>0.9 |
| ICANS any grade, n (%) |
14 (28%) |
52 (53%) |
0.004 |
| ICANS grade 3-4, n (%) |
9 (18%) |
18 (18%) |
>0.9 |
| Days with fever, Median (IQR) |
3 (2, 4) |
5 (3, 7) |
<0.001 |
| Fever 1st day, Median (IQR) |
3.00 (1.50, 5.00) |
3.00 (1.00, 5.00) |
0.7 |
| Time to ICANS (days), Median (IQR) |
7.0 (7.0, 8.8) |
7.0 (5.0, 9.3) |
0.4 |
| Toci doses, Median (IQR) |
0.00 (0.00, 0.00) |
1.00 (0.00, 1.00) |
<0.001 |
| Received toci, n (%) |
12 (24%) |
53 (54%) |
<0.001 |
| Dex doses, Median (IQR) |
0 (0, 5) |
2 (0, 13) |
0.001 |
| Received dex, n (%) |
16 (32%) |
65 (66%) |
<0.001 |
| ICE score min, Median (IQR) |
10.0 (6.0, 10.0) |
8.0 (3.0, 10.0) |
0.013 |
IPTW weighted toxicity table
Show code
theme_gtsummary_compact()
data1 = IPTW.data %>%
transmute(
"Product" = recode(CAR.T.Product.Type, "Breyanzi"="Liso-cel","Yescarta"="Axi-cel"),
#"Max CRS grade" = CRS.grade,
"CRS any grade" = ifelse( CRS.grade != 0, 1, 0),
"CRS grade 3-4" = ifelse( CRS.grade ==3 | CRS.grade == 4, 1, 0),
"Time to CRS (days)" = CRS.day,
#"Max ICANS grade" = ICANS.grade,
"ICANS any grade" = ifelse( ICANS.grade != 0,1,0),
"ICANS grade 3-4" = ifelse( ICANS.grade ==3 | ICANS.grade == 4,1,0),
"Days with fever" = fever.days,
"Fever 1st day" = fever.first.day,
"Time to ICANS (days)" = ICANS.day,
"Toci doses" = as.numeric(toci.doses),
"Received toci" = ifelse(toci.doses !=0,1,0),
"Dex doses" = as.numeric(dex.doses),
"Received dex" = ifelse(dex.doses !=0,1,0),
"ICE score min" = ICE.min,
weights
)
survey::svydesign(
id = ~0,
weights = ~weights,
data = data1,
fpc = NULL
) %>%
tbl_svysummary(
by = Product,
missing = "no",
statistic = list(
all_continuous() ~ "{median} ({p25}, {p75})",
all_categorical() ~ "{n} ({p}%)"),
include = c("CRS any grade","CRS grade 3-4","ICANS any grade","ICANS grade 3-4")
) %>%
bold_labels %>%
add_p()
| Characteristic |
Axi-cel, N = 86 |
Liso-cel, N = 41 |
p-value |
| CRS any grade |
73 (85%) |
27 (67%) |
0.040 |
| CRS grade 3-4 |
7 (7.8%) |
1 (3.0%) |
0.3 |
| ICANS any grade |
43 (50%) |
15 (36%) |
0.2 |
| ICANS grade 3-4 |
14 (17%) |
10 (25%) |
0.3 |
Table for ID complications
Show code
theme_gtsummary_compact()
dataset %>%
transmute(
"Product" = CAR.T.Product.Type,
"Positive BCx" = Pos.BCx,
"Positive CMV" = CMV,
"CMV level detectable" = ifelse(CMV.peak.level >0, 1, 0),
"CMV duration" = CMV.last.day - CMV.first.day,
"Cefepime doses" = cefepime.doses,
"Received cefepime" = ifelse(cefepime.doses >=1,1,0),
"Vancomycin doses" = vancomycin.doses
) %>%
tbl_summary(
by = "Product",
missing = "no",
#sort = all_categorical() ~ "frequency",
statistic = list(
all_continuous() ~ "{median} ({p25}, {p75})",
all_categorical() ~ "{n} ({p}%)"
)
) %>%
bold_labels %>%
add_p() %>%
add_stat_label() %>%
sort_p()
| Characteristic |
Breyanzi, N = 50 |
Yescarta, N = 99 |
p-value |
| Cefepime doses, Median (IQR) |
0 (0, 8) |
9 (0, 16) |
<0.001 |
| Received cefepime, n (%) |
21 (42%) |
68 (69%) |
0.002 |
| Vancomycin doses, Median (IQR) |
0.0 (0.0, 0.0) |
0.0 (0.0, 3.0) |
0.3 |
| Positive BCx, n (%) |
2 (4.0%) |
8 (8.1%) |
0.5 |
| CMV level detectable, n (%) |
6 (12%) |
9 (9.1%) |
0.6 |
| Positive CMV, n (%) |
15 (30%) |
26 (26%) |
0.6 |
| CMV duration, Median (IQR) |
19 (4, 26) |
14 (7, 34) |
0.8 |
Table for post-infusion cytopenias
Show code
theme_gtsummary_compact()
data1 <- dataset %>%
mutate(
CAR.T.Product.Type = recode(CAR.T.Product.Type,"Breyanzi"="Liso-cel","Yescarta"="Axi-cel")
)
data1 %>%
filter(Infused == 1) %>%
transmute(
"Product" = CAR.T.Product.Type,
"WBC min (10\U00B3/\U00B5L)" = WBC.min,
"WBC nadir day" = WBC_day_nadir,
"ANC min (10\U00B3/\U00B5L)" = ANC.min,
"ANC <500 (cells/\U00B5L)" = ifelse(ANC.min <0.5, "Yes","No"),
"Hgb min (g/dL)" = Hgb.min,
"Plt min (10\U00B3/\U00B5L)" = Plt.min,
"Neutropenic time (days)" = neutropenic.days
) %>%
tbl_summary(
by = "Product",
missing = "no",
#sort = all_categorical() ~ "frequency",
statistic = list(
all_continuous() ~ "{median} ({p25}, {p75})",
all_categorical() ~ "{n} ({p}%)"
)
) %>%
bold_labels %>%
add_p() %>%
add_stat_label() %>%
sort_p()
| Characteristic |
Axi-cel, N = 99 |
Liso-cel, N = 50 |
p-value |
| ANC min (10³/µL), Median (IQR) |
0.04 (0.00, 0.17) |
0.26 (0.10, 0.51) |
<0.001 |
| WBC min (10³/µL), Median (IQR) |
0.25 (0.14, 0.48) |
0.65 (0.37, 1.38) |
<0.001 |
| Neutropenic time (days), Median (IQR) |
6.0 (3.0, 10.0) |
2.0 (0.3, 5.0) |
<0.001 |
| Hgb min (g/dL), Median (IQR) |
8.20 (7.75, 8.85) |
8.80 (8.25, 10.10) |
0.001 |
| ANC <500 (cells/µL), n (%) |
92 (93%) |
37 (74%) |
0.001 |
| Plt min (10³/µL), Median (IQR) |
36 (18, 67) |
82 (32, 109) |
0.002 |
| WBC nadir day, Median (IQR) |
4.0 (3.0, 6.0) |
5.0 (3.0, 6.8) |
0.4 |
Table for day 30 counts
Show code
theme_gtsummary_compact()
data1 <- dataset %>%
mutate(
CAR.T.Product.Type = recode(CAR.T.Product.Type,"Breyanzi"="Liso-cel","Yescarta"="Axi-cel")
)
data1 %>%
transmute(
"Product" = CAR.T.Product.Type,
"WBC d30 (10\U00B3/\U00B5L)" = WBC.30,
"ANC d30 (10\U00B3/\U00B5L)" = ANC.30,
"ALC d30 (10\U00B3/\U00B5L)" = ALC.30,
"ANC <500 (cells/\U00B5L)" = ifelse(ANC.30 <0.5, "Yes","No"),
"Hgb d30 (g/dL)" = Hgb.30,
"Plt d30 (10\U00B3/\U00B5L)" = Plt.30,
) %>%
tbl_summary(
by = "Product",
missing = "no",
#sort = all_categorical() ~ "frequency",
statistic = list(
all_continuous() ~ "{median} ({p25}, {p75})",
all_categorical() ~ "{n} ({p}%)"
)
) %>%
bold_labels %>%
add_p() %>%
add_stat_label() %>%
sort_p()
| Characteristic |
Axi-cel, N = 99 |
Liso-cel, N = 50 |
p-value |
| Plt d30 (10³/µL), Median (IQR) |
63 (33, 117) |
102 (48, 145) |
0.049 |
| ANC d30 (10³/µL), Median (IQR) |
1.38 (0.78, 2.31) |
1.72 (1.15, 2.95) |
0.14 |
| WBC d30 (10³/µL), Median (IQR) |
2.59 (1.53, 3.73) |
2.90 (2.12, 4.07) |
0.4 |
| ANC <500 (cells/µL), n (%) |
14 (15%) |
5 (10%) |
0.5 |
| ALC d30 (10³/µL), Median (IQR) |
0.47 (0.24, 0.95) |
0.48 (0.33, 0.63) |
0.5 |
| Hgb d30 (g/dL), Median (IQR) |
10.40 (9.40, 11.55) |
10.50 (9.95, 11.20) |
0.6 |
Table for post-infusion inflammatory markers and other labs
Show code
theme_gtsummary_compact()
dataset %>%
mutate(
CAR.T.Product.Type = recode(CAR.T.Product.Type,"Breyanzi"="Liso-cel","Yescarta"="Axi-cel")
) %>%
transmute(
"Product" = CAR.T.Product.Type,
"ALT max (U/L)" = ALT.max,
"AST max (U/L)" = AST.max,
"CRP max (mg/L)" = CRP.max,
"D-dimer max (mg/L)" = ddimer.max,
"Ferritin max (ng/mL)" = ferritin.max,
"IL6 max (pg/mL)" = IL6.max,
"LDH max (U/L)" = LDH.max
) %>%
tbl_summary(
by = "Product",
missing = "no",
#sort = all_categorical() ~ "frequency",
statistic = list(
all_continuous() ~ "{median} ({p25}, {p75})",
all_categorical() ~ "{n} ({p}%)"
)
) %>%
bold_labels %>%
add_p() %>%
add_stat_label() %>%
sort_p()
| Characteristic |
Axi-cel, N = 99 |
Liso-cel, N = 50 |
p-value |
| CRP max (mg/L), Median (IQR) |
118 (57, 180) |
63 (9, 114) |
<0.001 |
| IL6 max (pg/mL), Median (IQR) |
207 (58, 1,165) |
55 (15, 481) |
0.001 |
| ALT max (U/L), Median (IQR) |
53 (36, 82) |
30 (22, 67) |
0.004 |
| D-dimer max (mg/L), Median (IQR) |
2.5 (1.5, 3.9) |
1.4 (0.7, 3.3) |
0.007 |
| Ferritin max (ng/mL), Median (IQR) |
1,217 (488, 2,520) |
783 (206, 1,709) |
0.017 |
| AST max (U/L), Median (IQR) |
36 (27, 60) |
28 (22, 49) |
0.073 |
| LDH max (U/L), Median (IQR) |
250 (189, 355) |
215 (176, 346) |
0.2 |
Table for post-infusion inflammatory markers and other labs, stratified by product and CRS
Show code
theme_gtsummary_compact()
dataset %>%
mutate(
CAR.T.Product.Type = recode(CAR.T.Product.Type, "Breyanzi" = "Liso-cel", "Yescarta" = "Axi-cel")
) %>%
transmute(
"ALT max (U/L)" = ALT.max,
"AST max (U/L)" = AST.max,
"CRP max (mg/L)" = CRP.max,
"D-dimer max (mg/L)" = ddimer.max,
"Ferritin max (ng/mL)" = ferritin.max,
"IL6 max (pg/mL)" = IL6.max,
"LDH max (U/L)" = LDH.max,
CRS.grade = recode(CRS.grade, "0" = "0", "1" = "1-2", "2" = "1-2", "3" = "3+", "4" = "3+")
) %>%
tbl_summary(
by = CRS.grade,
missing = "no",
statistic = list(
all_continuous() ~ "{median} ({p25}, {p75})",
all_categorical() ~ "{n} ({p}%)"
)
) %>%
modify_spanning_header(all_stat_cols() ~ "**CRS grade**") %>%
modify_header(all_stat_cols() ~ "**{level}**<br>N = {n} ({style_percent(p)}%)") %>%
bold_labels() %>%
add_p() %>%
add_stat_label()
| Characteristic |
CRS grade
|
p-value |
0 N = 29 (19%) |
1-2 N = 111 (74%) |
3+ N = 9 (6.0%) |
| ALT max (U/L), Median (IQR) |
23 (20, 31) |
57 (33, 85) |
68 (44, 158) |
<0.001 |
| AST max (U/L), Median (IQR) |
23 (20, 30) |
36 (27, 58) |
57 (42, 83) |
<0.001 |
| CRP max (mg/L), Median (IQR) |
18 (6, 45) |
114 (62, 168) |
160 (123, 203) |
<0.001 |
| D-dimer max (mg/L), Median (IQR) |
1.0 (0.6, 2.5) |
2.3 (1.4, 3.7) |
9.2 (8.1, 15.1) |
<0.001 |
| Ferritin max (ng/mL), Median (IQR) |
283 (174, 491) |
1,217 (556, 2,113) |
11,312 (8,863, 14,982) |
<0.001 |
| IL6 max (pg/mL), Median (IQR) |
20 (13, 54) |
174 (56, 739) |
7,125 (3,064, 21,316) |
<0.001 |
| LDH max (U/L), Median (IQR) |
175 (151, 226) |
250 (193, 351) |
708 (594, 1,163) |
<0.001 |
Show code
dataset %>%
mutate(
CAR.T.Product.Type = recode(CAR.T.Product.Type, "Breyanzi" = "Liso-cel", "Yescarta" = "Axi-cel")
) %>%
transmute(
"ALT max (U/L)" = ALT.max,
"AST max (U/L)" = AST.max,
"CRP max (mg/L)" = CRP.max,
"D-dimer max (mg/L)" = ddimer.max,
"Ferritin max (ng/mL)" = ferritin.max,
"IL6 max (pg/mL)" = IL6.max,
"LDH max (U/L)" = LDH.max,
ICANS.grade = recode(ICANS.grade, "0" = "0", "1" = "1-2", "2" = "1-2", "3" = "3+", "4" = "3+")
) %>%
tbl_summary(
by = ICANS.grade,
missing = "no",
statistic = list(
all_continuous() ~ "{median} ({p25}, {p75})",
all_categorical() ~ "{n} ({p}%)"
)
) %>%
modify_spanning_header(all_stat_cols() ~ "**ICANS grade**") %>%
modify_header(all_stat_cols() ~ "**{level}**<br>N = {n} ({style_percent(p)}%)") %>%
bold_labels() %>%
add_p() %>%
add_stat_label()
| Characteristic |
ICANS grade
|
p-value |
0 N = 83 (56%) |
1-2 N = 39 (26%) |
3+ N = 27 (18%) |
| ALT max (U/L), Median (IQR) |
31 (23, 58) |
62 (41, 88) |
89 (52, 158) |
<0.001 |
| AST max (U/L), Median (IQR) |
27 (21, 39) |
44 (34, 59) |
70 (31, 93) |
<0.001 |
| CRP max (mg/L), Median (IQR) |
62 (19, 116) |
123 (66, 191) |
148 (110, 198) |
<0.001 |
| D-dimer max (mg/L), Median (IQR) |
1.6 (0.8, 2.6) |
2.5 (1.6, 3.7) |
6.2 (3.3, 11.6) |
<0.001 |
| Ferritin max (ng/mL), Median (IQR) |
530 (261, 1,327) |
1,619 (868, 2,579) |
4,174 (1,631, 9,710) |
<0.001 |
| IL6 max (pg/mL), Median (IQR) |
54 (23, 154) |
223 (111, 1,168) |
1,454 (686, 5,459) |
<0.001 |
| LDH max (U/L), Median (IQR) |
218 (165, 280) |
231 (189, 391) |
357 (248, 623) |
<0.001 |
Table for cardiac/BP results
Show code
theme_gtsummary_compact()
dataset %>%
mutate(
CAR.T.Product.Type = recode(CAR.T.Product.Type,"Breyanzi"="Liso-cel","Yescarta"="Axi-cel")
) %>%
transmute(
"Product" = CAR.T.Product.Type,
"Pre-LD SBP (mmHg)" = SBP.preLD,
"Pre-LD DBP (mmHg)" = DBP.preLD,
"Pre-LD MAP (mmHg)" = MAP.preLD,
"Max SBP drop (mmHg)" = SBP.preLD - SBP.min,
"Max DBP drop (mmHg)" = DBP.preLD - DBP.min,
"Max MAP drop (mmHg)" = MAP.preLD - MAP.min,
"Positive troponin (\u22650.03 ng/mL)" = ifelse(!is.na(trop.max) & trop.max >=0.03,1,0)
) %>%
tbl_summary(
by = "Product",
missing = "no",
#sort = all_categorical() ~ "frequency",
statistic = list(
all_continuous() ~ "{median} ({p25}, {p75})",
all_categorical() ~ "{n} ({p}%)"
)
) %>%
bold_labels %>%
add_p() %>%
add_stat_label() %>%
sort_p()
| Characteristic |
Axi-cel, N = 99 |
Liso-cel, N = 50 |
p-value |
| Max DBP drop (mmHg), Median (IQR) |
27 (20, 34) |
20 (14, 25) |
<0.001 |
| Max MAP drop (mmHg), Median (IQR) |
29 (23, 36) |
23 (17, 28) |
<0.001 |
| Max SBP drop (mmHg), Median (IQR) |
35 (28, 45) |
27 (19, 37) |
0.001 |
| Pre-LD SBP (mmHg), Median (IQR) |
116 (108, 127) |
116 (111, 123) |
0.6 |
| Positive troponin (≥0.03 ng/mL), n (%) |
4 (4.0%) |
3 (6.0%) |
0.7 |
| Pre-LD MAP (mmHg), Median (IQR) |
87 (81, 95) |
88 (83, 94) |
0.8 |
| Pre-LD DBP (mmHg), Median (IQR) |
74 (67, 80) |
74 (69, 77) |
0.8 |
STACKED BAR GRAPH
Stacked bar graph of toxicity for liso-cel and axi-cel
Show code
combined_data <- rbind(
dataset %>%
count(CAR.T.Product.Type, CRS.grade) %>%
group_by(CAR.T.Product.Type) %>%
mutate(
total = sum(n[CRS.grade != 0]),
pct = prop.table(n) * 100,
total_pct = sum(pct[CRS.grade != 0]),
Grade = factor(CRS.grade, levels = c(0, 4, 3, 2, 1)),
CAR.T.Product.Type = recode(CAR.T.Product.Type, "Breyanzi" = "Liso-cel", "Yescarta" = "Axi-cel"),
Category = "CRS"
),
dataset %>%
count(CAR.T.Product.Type, ICANS.grade) %>%
group_by(CAR.T.Product.Type) %>%
mutate(
total = sum(n[ICANS.grade != 0]),
pct = prop.table(n) * 100,
total_pct = sum(pct[ICANS.grade != 0]),
Grade = factor(ICANS.grade, levels = c(0, 4, 3, 2, 1)),
CAR.T.Product.Type = recode(CAR.T.Product.Type, "Breyanzi" = "Liso-cel", "Yescarta" = "Axi-cel"),
Category = "ICANS"
)
)
ggplot(combined_data) +
aes(x = CAR.T.Product.Type, y = pct, fill = Grade) +
geom_bar(stat = "identity", position = "stack", data = . %>% filter(Grade != 0)) +
geom_text(aes(label = paste0(sprintf("%1.1f", pct), "% (",n,")")),
data = . %>% filter(Grade != 0),
position = position_stack(vjust = 0.5)) +
geom_text( aes(label = paste0(sprintf("%1.1f", total_pct), "% (",total,")"), x = CAR.T.Product.Type, y = total_pct + 7, vjust = 0),
data = . %>% filter(Grade != 0),
color = "#104a8e") +
#geom_text(aes(label = paste0(sprintf("%1.1f", pct), "% (", n, ")")), position = position_dodge(width = 0.9), vjust = 0.5) +
#geom_text(aes(label = paste0(sprintf("%1.1f", total_pct), "% (", total, ")"), y = total_pct + 7), color = "#104a8e") +
facet_wrap(~Category, scales = "free_y") +
ylab("Proportion of patients (%)") +
xlab(NULL) +
#ggtitle("Comparison of CRS and ICANS grades") +
theme_classic()+
scale_fill_brewer(palette = "Pastel1") +
scale_y_continuous(breaks = seq(0, 100, by = 20), limits = c(0, 100)) +
theme(
axis.title = element_text(size = 16),
axis.text = element_text(size = 16),
legend.title = element_text(size = 16),
legend.text = element_text(size = 14),
axis.text.x = element_text(angle = 45, hjust = 1)
)

COMPETING RISK ANALYSIS
Cumulative incidence of death
Show code
theme_gtsummary_compact()
data1 <- filter(dataset, Infused == 1) %>%
select(Days.to.DLC, Alive.RM.NRM, CAR.T.Product.Type, Age, Largest.lesion, ALC.preLD, HCT.CI, LDH.preLD) %>%
mutate(
Alive.RM.NRM = as.factor(recode(Alive.RM.NRM,"0"="Alive","1"="Death from cancer","2"="Death from other causes")),
CAR.T.Product.Type = factor(recode(CAR.T.Product.Type, "Breyanzi" = "Liso-cel", "Yescarta" = "Axi-cel"), levels = c("Liso-cel","Axi-cel") ),
Months.to.DLC = Days.to.DLC/30
)
cum <- tidycmprsk::cuminc(Surv( Months.to.DLC , Alive.RM.NRM) ~ CAR.T.Product.Type, data1, rho=0, conf.level=0.95)
cum %>%
ggcuminc(
#risk.table=TRUE,
theme = theme_classic(),
outcome = c("Death from cancer","Death from other causes")
) +
labs(
x = "Time (months)",
y = "Probability of death"
) +
ylim(0,1) +
scale_x_continuous(breaks = seq(0, 36, by = 6), limits=c(0, 36)) +
#add_confidence_interval() +
add_risktable(
size = 5,
risktable_stats = c("n.risk"),
risktable_height = 0.2,
stats_label = c("Number at risk"),
theme = theme_risktable_default(axis.text.y.size = 14, plot.title.size = 14)
)+
add_pvalue() +
theme(
legend.position = c(0.22, 0.8),
text = element_text(size = 16) # Set text size to 16
)
Show code
cum %>%
tbl_cuminc(
times = c(12),
outcomes = c("Death from cancer","Death from other causes"),
label_header = c("**{time}-month cuminc**")
) %>%
add_p()
| Characteristic |
12-month cuminc |
p-value |
| Death from cancer |
| CAR.T.Product.Type |
|
0.5 |
| Liso-cel |
27% (14%, 42%) |
|
| Axi-cel |
39% (28%, 50%) |
|
| Death from other causes |
| CAR.T.Product.Type |
|
>0.9 |
| Liso-cel |
7.3% (1.8%, 18%) |
|
| Axi-cel |
5.2% (1.7%, 12%) |
|
Show code
uv_tab<-crr(Surv(Days.to.DLC, Alive.RM.NRM) ~ CAR.T.Product.Type, data = data1) %>%
tbl_regression(exp = TRUE)
mv_tab<-crr(Surv(Days.to.DLC, Alive.RM.NRM) ~ CAR.T.Product.Type + Age + Largest.lesion + ALC.preLD + LDH.preLD, data = data1) %>%
tbl_regression(exp = TRUE)
1 cases omitted due to missing values
Show code
tbl_merge(
tbls = list(uv_tab, mv_tab), # combine
tab_spanner = c("**Univariate**", "**Multivariable**")) # set header names
| Characteristic |
Univariate
|
Multivariable
|
| HR |
95% CI |
p-value |
HR |
95% CI |
p-value |
| CAR.T.Product.Type |
|
|
|
|
|
|
| Liso-cel |
— |
— |
|
— |
— |
|
| Axi-cel |
1.22 |
0.70, 2.13 |
0.5 |
1.10 |
0.61, 1.99 |
0.8 |
| Age |
|
|
|
1.00 |
0.98, 1.02 |
0.8 |
| Largest.lesion |
|
|
|
1.10 |
1.03, 1.18 |
0.007 |
| ALC.preLD |
|
|
|
1.31 |
1.20, 1.43 |
<0.001 |
| LDH.preLD |
|
|
|
1.00 |
1.00, 1.00 |
<0.001 |
KAPLAN-MEIER ANALYSIS
Calculate length of follow-up
Show code
library(prodlim)
library(haven)
data1 = dataset %>%
mutate(
Reverse_death = ifelse(Death == 1, 0,1)
)
#quantile(prodlim(Hist(time = Days.to.DLC/30, Death )~1, data = data1, reverse = TRUE ) )
reverse_km_OS <- survfit(Surv(Days.to.DLC/30, Reverse_death) ~ 1, data1)
reverse_km_OS
Call: survfit(formula = Surv(Days.to.DLC/30, Reverse_death) ~ 1, data = data1)
n events median 0.95LCL 0.95UCL
[1,] 149 83 27.1 22.6 38.2
Show code
reverse_km_OS_breyanzi <- survfit(Surv(Days.to.DLC/30, Reverse_death) ~ 1, filter(data1, CAR.T.Product.Type == "Breyanzi") )
reverse_km_OS_breyanzi
Call: survfit(formula = Surv(Days.to.DLC/30, Reverse_death) ~ 1, data = filter(data1,
CAR.T.Product.Type == "Breyanzi"))
n events median 0.95LCL 0.95UCL
[1,] 50 30 18.5 12.9 25.9
Show code
reverse_km_OS_yescarta <- survfit(Surv(Days.to.DLC/30, Reverse_death) ~ 1, filter(data1, CAR.T.Product.Type == "Yescarta") )
reverse_km_OS_yescarta
Call: survfit(formula = Surv(Days.to.DLC/30, Reverse_death) ~ 1, data = filter(data1,
CAR.T.Product.Type == "Yescarta"))
n events median 0.95LCL 0.95UCL
[1,] 99 53 43 32.5 51.5
KM for OS, whole cohort
Show code
data1 = filter(dataset, Infused == 1)
km_OS <- survfit(Surv(Days.to.DLC/30, Death) ~ 1, data1)
km_OS
Call: survfit(formula = Surv(Days.to.DLC/30, Death) ~ 1, data = data1)
n events median 0.95LCL 0.95UCL
[1,] 149 66 16.3 12.1 53.5
Show code
#autoplot(km_Regain)
OS_plot <- ggsurvplot(km_OS,
pval=FALSE,
conf.int = TRUE,
risk.table = TRUE, # Add risk table
fontsize = 6,
risk.table.col = "strata", # Change risk table color by groups
tables.height = 0.25,
tables.theme = theme_cleantable(),
xlab="Time (months)", ylab = "Overall survival",
xlim = c(0,36), break.x.by = c(180/30),
ylim = c(0,1), break.y.by = c(0.25),
legend = "none",
surv.scale="percent",
font.main = c(16, "plain", "black"),
font.x = c(16, "plain", "black"),
font.y = c(16, "plain", "black"),
font.caption = c(16, "plain", "black"),
font.tickslab = c(16, "plain", "black")
)
OS_plot

KM for OS, whole cohort
Show code
data1 = filter(dataset, Infused == 1)
km_PFS <- survfit(Surv(Days.to.relapse.death.or.DLC/30, Relapse.or.death) ~ 1, data1)
km_PFS
Call: survfit(formula = Surv(Days.to.relapse.death.or.DLC/30, Relapse.or.death) ~
1, data = data1)
n events median 0.95LCL 0.95UCL
[1,] 149 84 7.43 5.33 19.6
Show code
#autoplot(km_Regain)
PFS_plot <- ggsurvplot(km_PFS,
pval=FALSE,
conf.int = TRUE,
risk.table = TRUE, # Add risk table
fontsize = 6,
risk.table.col = "strata", # Change risk table color by groups
tables.height = 0.25,
tables.theme = theme_cleantable(),
xlab="Time (months)", ylab = "Progression-free survival",
xlim = c(0,36), break.x.by = c(180/30),
ylim = c(0,1), break.y.by = c(0.25),
legend = "none",
surv.scale="percent",
font.main = c(16, "plain", "black"),
font.x = c(16, "plain", "black"),
font.y = c(16, "plain", "black"),
font.caption = c(16, "plain", "black"),
font.tickslab = c(16, "plain", "black")
)
PFS_plot

Create KM for OS
Show code
data1 = filter(dataset, Infused == 1) %>%
mutate(
Reverse_death = ifelse(Death == 1, 0,1)
)
km_OS <- survfit(Surv(Days.to.DLC/30, Death) ~ CAR.T.Product.Type, data1)
km_OS
Call: survfit(formula = Surv(Days.to.DLC/30, Death) ~ CAR.T.Product.Type,
data = data1)
n events median 0.95LCL 0.95UCL
CAR.T.Product.Type=Breyanzi 50 20 15.6 13.2 NA
CAR.T.Product.Type=Yescarta 99 46 16.0 9.4 NA
Show code
med_OS <- surv_median(km_OS)
p.logrank <- survdiff(Surv(Days.to.DLC/30, Death) ~ CAR.T.Product.Type, data1)$pvalue
oneYr <- summary(km_OS,times=c(12))
oneYr
Call: survfit(formula = Surv(Days.to.DLC/30, Death) ~ CAR.T.Product.Type,
data = data1)
CAR.T.Product.Type=Breyanzi
time n.risk n.event survival std.err
12.000 21.000 14.000 0.655 0.077
lower 95% CI upper 95% CI
0.520 0.825
CAR.T.Product.Type=Yescarta
time n.risk n.event survival std.err
12.0000 41.0000 35.0000 0.5543 0.0565
lower 95% CI upper 95% CI
0.4540 0.6769
Show code
oneYr$surv[1]- oneYr$surv[2] # Difference in survival at 1 yr for Breyanzi vs Yescarta
[1] 0.1008576
Show code
print("Difference in survival: ")
[1] "Difference in survival: "
Show code
diffSE <- sqrt(oneYr$std.err[2]^2 + oneYr$std.err[1]^2) # calculate the standard error
#Calculate the 95% CI for the difference
print("95% CI: ")
[1] "95% CI: "
Show code
oneYr$surv[1] - oneYr$surv[2] - 1.96 * diffSE
[1] -0.08635184
Show code
oneYr$surv[1] - oneYr$surv[2] + 1.96 * diffSE
[1] 0.288067
Show code
zStat <- (oneYr$surv[1] - oneYr$surv[2])/diffSE # calculate the c-test statistic
print("p-value: ")
[1] "p-value: "
Show code
p = 2 * pnorm(abs(zStat), lower.tail = FALSE) # calculate a two-sided p-value
#autoplot(km_Regain)
OS_plot <- ggsurvplot(km_OS,
pval=FALSE,
conf.int = TRUE,
risk.table = TRUE, # Add risk table
fontsize = 6,
risk.table.col = "strata", # Change risk table color by groups
tables.height = 0.25,
tables.theme = theme_cleantable(),
xlab="Time (months)", ylab = "Overall survival",
xlim = c(0,36), break.x.by = c(180/30),
ylim = c(0,1), break.y.by = c(0.25),
legend.labs = c("Liso-cel","Axi-cel"),
legend = "none",
surv.scale="percent",
font.main = c(16, "plain", "black"),
font.x = c(16, "plain", "black"),
font.y = c(16, "plain", "black"),
font.caption = c(16, "plain", "black"),
font.tickslab = c(16, "plain", "black")
)
OS_plot$plot <- OS_plot$plot +
geom_vline(xintercept = 12, linetype = "dashed", color = "steelblue") +
geom_hline(yintercept = 0.5, linetype = "dashed", color = "black") +
annotate("text", x = 12.5, y = 0.83, label = paste("Liso-cel vs axi-cel: 1-year OS\n", signif(oneYr$surv[1]*100, 2), "% vs ", signif(oneYr$surv[2]*100, 2), "%, p =", signif(p,2)), color = "steelblue", hjust = 0, vjust = -0.5, size = 3) +
annotate("text", x = 13, y = 0, label = paste("Liso-cel vs axi-cel,\nmedian OS:\n", signif(med_OS$median[1], 2), "vs", signif(med_OS$median[2], 2), "months, p =", signif(p.logrank,2)), color = "black", hjust = 0, vjust = -0.5, size = 3, fontface = "bold")
OS_plot

Create KM for PFS, stratified by product
Show code
data1 <- filter(dataset, Infused == 1) #%>%
#filter(Best.response == "CR" | Best.response == "PR") ## To view DOR instead of PFS
km_RFS <- survfit(Surv(Days.to.relapse.death.or.DLC/30, Relapse.or.death) ~ CAR.T.Product.Type, data = data1 )
km_RFS
Call: survfit(formula = Surv(Days.to.relapse.death.or.DLC/30, Relapse.or.death) ~
CAR.T.Product.Type, data = data1)
n events median 0.95LCL 0.95UCL
CAR.T.Product.Type=Breyanzi 50 30 7.17 4.07 22.6
CAR.T.Product.Type=Yescarta 99 54 9.50 4.57 41.1
Show code
med_RFS <- surv_median(km_RFS)
p.logrank <- survdiff(Surv(Days.to.relapse.death.or.DLC/30, Relapse.or.death) ~ CAR.T.Product.Type, data1)$pvalue
oneYr <- summary(km_RFS,times=c(12))
oneYr
Call: survfit(formula = Surv(Days.to.relapse.death.or.DLC/30, Relapse.or.death) ~
CAR.T.Product.Type, data = data1)
CAR.T.Product.Type=Breyanzi
time n.risk n.event survival std.err
12.0000 12.0000 27.0000 0.3839 0.0776
lower 95% CI upper 95% CI
0.2584 0.5705
CAR.T.Product.Type=Yescarta
time n.risk n.event survival std.err
12.0000 34.0000 46.0000 0.4591 0.0556
lower 95% CI upper 95% CI
0.3621 0.5821
Show code
oneYr$surv[1]- oneYr$surv[2] # Difference in survival at 1 yr for Breyanzi vs Yescarta
[1] -0.07517689
Show code
print("Difference in survival: ")
[1] "Difference in survival: "
Show code
diffSE <- sqrt(oneYr$std.err[2]^2 + oneYr$std.err[1]^2) # calculate the standard error
#Calculate the 95% CI for the difference
print("95% CI: ")
[1] "95% CI: "
Show code
oneYr$surv[1] - oneYr$surv[2] - 1.96 * diffSE
[1] -0.2622901
Show code
oneYr$surv[1] - oneYr$surv[2] + 1.96 * diffSE
[1] 0.1119363
Show code
zStat <- (oneYr$surv[1] - oneYr$surv[2])/diffSE # calculate the c-test statistic
print("p-value: ")
[1] "p-value: "
Show code
p = 2 * pnorm(abs(zStat), lower.tail = FALSE) # calculate a two-sided p-value
#autoplot(km_Regain)
RFS_plot <- ggsurvplot(km_RFS,
pval=FALSE,
conf.int = TRUE,
risk.table = TRUE, # Add risk table
fontsize = 6,
risk.table.col = "strata", # Change risk table color by groups
tables.height = 0.25,
tables.theme = theme_cleantable(),
xlab="Time (months)", ylab = "Progression-free survival",
xlim = c(0,36), break.x.by = c(180/30),
ylim = c(0,1), break.y.by = c(0.25),
legend.labs = c("Liso-cel","Axi-cel"),
legend = "none",
surv.scale="percent",
font.main = c(16, "plain", "black"),
font.x = c(16, "plain", "black"),
font.y = c(16, "plain", "black"),
font.caption = c(16, "plain", "black"),
font.tickslab = c(16, "plain", "black")
)
RFS_plot$plot <- RFS_plot$plot +
geom_vline(xintercept = 12, linetype = "dashed", color = "steelblue") +
geom_hline(yintercept = 0.5, linetype = "dashed", color = "black") +
annotate("text", x = 12.5, y = 0.83, label = paste("Liso-cel vs axi-cel: 1-year PFS\n", signif(oneYr$surv[1]*100, 2), "% vs ", signif(oneYr$surv[2]*100, 2), "%, p =", signif(p,2)), color = "steelblue", hjust = 0, vjust = -0.5, size = 3) +
annotate("text", x = 13, y = .5, label = paste("Liso-cel vs axi-cel,\nmedian PFS:\n", signif(med_RFS$median[1], 2), "vs", signif(med_RFS$median[2], 2), "months, p =", signif(p.logrank,2)), color = "black", hjust = 0, vjust = -0.5, size = 3, fontface = "bold")
RFS_plot

Create KM for DOR, stratified by product
Show code
data1 <- filter(dataset, Infused == 1) %>%
filter(Best.response == "CR" | Best.response == "PR") ## To view DOR instead of PFS
km_DOR <- survfit(Surv( (Days.to.relapse.death.or.DLC-Days.to.response)/30, Relapse.or.death) ~ CAR.T.Product.Type, data = data1 )
km_DOR
Call: survfit(formula = Surv((Days.to.relapse.death.or.DLC - Days.to.response)/30,
Relapse.or.death) ~ CAR.T.Product.Type, data = data1)
n events median 0.95LCL 0.95UCL
CAR.T.Product.Type=Breyanzi 40 20 11.0 5.83 NA
CAR.T.Product.Type=Yescarta 76 31 40.2 9.93 NA
Show code
med_DOR <- surv_median(km_DOR)
p.logrank <- survdiff(Surv( (Days.to.relapse.death.or.DLC-Days.to.response)/30, Relapse.or.death) ~ CAR.T.Product.Type, data1)$pvalue
oneYr <- summary(km_DOR,times=c(12))
oneYr
Call: survfit(formula = Surv((Days.to.relapse.death.or.DLC - Days.to.response)/30,
Relapse.or.death) ~ CAR.T.Product.Type, data = data1)
CAR.T.Product.Type=Breyanzi
time n.risk n.event survival std.err
12.0000 12.0000 17.0000 0.4830 0.0906
lower 95% CI upper 95% CI
0.3344 0.6977
CAR.T.Product.Type=Yescarta
time n.risk n.event survival std.err
12.0000 34.0000 23.0000 0.6054 0.0643
lower 95% CI upper 95% CI
0.4916 0.7455
Show code
oneYr$surv[1]- oneYr$surv[2] # Difference in survival at 1 yr for Breyanzi vs Yescarta
[1] -0.1223713
Show code
print("Difference in survival: ")
[1] "Difference in survival: "
Show code
diffSE <- sqrt(oneYr$std.err[2]^2 + oneYr$std.err[1]^2) # calculate the standard error
#Calculate the 95% CI for the difference
print("95% CI: ")
[1] "95% CI: "
Show code
oneYr$surv[1] - oneYr$surv[2] - 1.96 * diffSE
[1] -0.3401687
Show code
oneYr$surv[1] - oneYr$surv[2] + 1.96 * diffSE
[1] 0.09542613
Show code
zStat <- (oneYr$surv[1] - oneYr$surv[2])/diffSE # calculate the c-test statistic
print("p-value: ")
[1] "p-value: "
Show code
p = 2 * pnorm(abs(zStat), lower.tail = FALSE) # calculate a two-sided p-value
#autoplot(km_Regain)
DOR_plot <- ggsurvplot(km_DOR,
pval=FALSE,
conf.int = TRUE,
risk.table = TRUE, # Add risk table
fontsize = 6,
risk.table.col = "strata", # Change risk table color by groups
tables.height = 0.25,
tables.theme = theme_cleantable(),
xlab="Time (months)", ylab = "Progression-free survival",
xlim = c(0,36), break.x.by = c(180/30),
ylim = c(0,1), break.y.by = c(0.25),
legend.labs = c("Liso-cel","Axi-cel"),
legend = "none",
surv.scale="percent",
font.main = c(16, "plain", "black"),
font.x = c(16, "plain", "black"),
font.y = c(16, "plain", "black"),
font.caption = c(16, "plain", "black"),
font.tickslab = c(16, "plain", "black")
)
DOR_plot$plot <- DOR_plot$plot +
geom_vline(xintercept = 12, linetype = "dashed", color = "steelblue") +
geom_hline(yintercept = 0.5, linetype = "dashed", color = "black") +
annotate("text", x = 12.5, y = 0.83, label = paste("Liso-cel vs axi-cel: 1-year DOR\n", signif(oneYr$surv[1]*100, 2), "% vs ", signif(oneYr$surv[2]*100, 2), "%, p =", signif(p,2)), color = "steelblue", hjust = 0, vjust = -0.5, size = 3) +
annotate("text", x = 13, y = .5, label = paste("Liso-cel vs axi-cel,\nmedian DOR:\n", signif(med_DOR$median[1], 2), "vs", signif(med_DOR$median[2], 2), "months, p =", signif(p.logrank,2)), color = "black", hjust = 0, vjust = -0.5, size = 3, fontface = "bold")
DOR_plot

Combined KM with OS and PFS
Show code
splots <- list()
splots[[1]] = OS_plot
splots[[2]] = RFS_plot
arrange_ggsurvplots(splots, print = TRUE,
ncol = 2, nrow = 1, risk.table.height = 0.25)

Create KM for OS stratified by best response
Show code
km_OS <- survfit(Surv(Days.to.DLC/30, Death) ~ Best.response, data = filter(dataset, Infused == 1 & Best.response != "SD"))
km_OS
Call: survfit(formula = Surv(Days.to.DLC/30, Death) ~ Best.response,
data = filter(dataset, Infused == 1 & Best.response != "SD"))
n events median 0.95LCL 0.95UCL
Best.response=CR 77 21 NA 53.50 NA
Best.response=PD 32 25 5.5 3.67 9.7
Best.response=PR 39 19 13.5 6.77 NA
Show code
#autoplot(km_Regain)
OS_plot <- ggsurvplot(km_OS,
pval=TRUE,
conf.int = TRUE,
risk.table = TRUE, # Add risk table
fontsize = 6,
risk.table.col = "strata", # Change risk table color by groups
tables.height = 0.3,
tables.theme = theme_cleantable(),
#surv.median.line = "hv", # Specify median survival
#ggtheme = theme_bw(), # Change ggplot2 theme
#palette = c("#E7B800", "#2E9FDF"),
xlab="Time (months)", ylab = "Overall survival",
xlim = c(0,72), break.x.by = c(12),
ylim = c(0,1), break.y.by = c(0.25),
legend.labs = c("CR","PD", "PR"),
legend = "none",
surv.scale="percent",
font.main = c(16, "plain", "black"),
font.x = c(16, "plain", "black"),
font.y = c(16, "plain", "black"),
font.caption = c(16, "plain", "black"),
font.tickslab = c(16, "plain", "black")
)
OS_plot

Create KM for OS stratified by Bulky disease (>=5cm) status
Show code
km_OS <- survfit(Surv(Days.to.DLC/30, Death) ~ Bulky, data = filter(dataset, Infused == 1 | Best.response != "") )
km_OS
Call: survfit(formula = Surv(Days.to.DLC/30, Death) ~ Bulky, data = filter(dataset,
Infused == 1 | Best.response != ""))
n events median 0.95LCL 0.95UCL
Bulky=0 105 39 43.23 16.0 NA
Bulky=1 44 27 6.37 4.7 13.5
Show code
#autoplot(km_Regain)
OS_plot <- ggsurvplot(km_OS,
pval=TRUE,
conf.int = TRUE,
risk.table = TRUE, # Add risk table
fontsize = 6,
risk.table.col = "strata", # Change risk table color by groups
tables.height = 0.25,
tables.theme = theme_cleantable(),
xlab="Time (months)", ylab = "Overall survival",
xlim = c(0,72), break.x.by = c(12),
ylim = c(0,1), break.y.by = c(0.25),
legend.labs = c("Non-bulky","Bulky"),
legend = "none",
surv.scale="percent",
font.main = c(16, "plain", "black"),
font.x = c(16, "plain", "black"),
font.y = c(16, "plain", "black"),
font.caption = c(16, "plain", "black"),
font.tickslab = c(16, "plain", "black")
)
OS_plot

Create KM for OS stratified by Breyanzi out-of-spec (EAP) status
Show code
km_OS <- survfit(Surv(Days.to.DLC, Death) ~ EAP, data = filter(dataset, CAR.T.Product.Type == "Breyanzi") )
km_OS
Call: survfit(formula = Surv(Days.to.DLC, Death) ~ EAP, data = filter(dataset,
CAR.T.Product.Type == "Breyanzi"))
n events median 0.95LCL 0.95UCL
EAP=0 39 16 409 357 NA
EAP=1 11 4 NA 252 NA
Show code
OS_plot <- ggsurvplot(km_OS,
pval=TRUE,
conf.int = TRUE,
risk.table = TRUE, # Add risk table
fontsize = 6,
risk.table.col = "strata", # Change risk table color by groups
tables.height = 0.25,
tables.theme = theme_cleantable(),
xlab="Time (days)", ylab = "Overall survival",
xlim = c(0,1080), break.x.by = c(180),
ylim = c(0,1), break.y.by = c(0.25),
legend.labs = c("In-spec", "Out-of-spec"),
legend = "none",
surv.scale="percent",
font.main = c(16, "plain", "black"),
font.x = c(16, "plain", "black"),
font.y = c(16, "plain", "black"),
font.caption = c(16, "plain", "black"),
font.tickslab = c(16, "plain", "black")
)
OS_plot

Create KM for OS stratified by LDH status (<210 vs >=210 U/L)
Show code
data1 = filter(dataset, Infused == 1)
km_OS <- survfit(Surv(Days.to.DLC/30, Death) ~ High.LDH, data1)
km_OS
Call: survfit(formula = Surv(Days.to.DLC/30, Death) ~ High.LDH, data = data1)
1 observation deleted due to missingness
n events median 0.95LCL 0.95UCL
High.LDH=0 84 29 43.23 24.30 NA
High.LDH=1 64 36 6.77 4.57 11.9
Show code
#autoplot(km_Regain)
OS_plot <- ggsurvplot(km_OS,
pval=TRUE,
conf.int = TRUE,
risk.table = TRUE, # Add risk table
fontsize = 6,
risk.table.col = "strata", # Change risk table color by groups
tables.height = 0.25,
tables.theme = theme_cleantable(),
#surv.median.line = "hv", # Specify median survival
#ggtheme = theme_bw(), # Change ggplot2 theme
#palette = c("#E7B800", "#2E9FDF"),
xlab="Time (months)", ylab = "Overall survival",
xlim = c(0,72), break.x.by = c(12),
ylim = c(0,1), break.y.by = c(0.25),
legend.labs = c("LDH <210 U/L", "LDH \u2265210 U/L"),
legend = "none",
surv.scale="percent",
font.main = c(16, "plain", "black"),
font.x = c(16, "plain", "black"),
font.y = c(16, "plain", "black"),
font.caption = c(16, "plain", "black"),
font.tickslab = c(16, "plain", "black")
)
OS_plot

Create KM for OS stratified by HCT-CI status (>=3 vs <3)
Show code
data1 = filter(dataset, Infused == 1) %>%
mutate(
High.HCT.CI = ifelse(HCT.CI >=3,1,0) )
km_OS <- survfit(Surv(Days.to.DLC/30, Death) ~ High.HCT.CI, data1 )
km_OS
Call: survfit(formula = Surv(Days.to.DLC/30, Death) ~ High.HCT.CI,
data = data1)
n events median 0.95LCL 0.95UCL
High.HCT.CI=0 100 42 16.3 13.07 NA
High.HCT.CI=1 49 24 16.0 8.97 NA
Show code
OS_plot <- ggsurvplot(km_OS,
pval=TRUE,
conf.int = TRUE,
risk.table = TRUE, # Add risk table
fontsize = 6,
risk.table.col = "strata", # Change risk table color by groups
tables.height = 0.25,
tables.theme = theme_cleantable(),
#surv.median.line = "hv", # Specify median survival
#ggtheme = theme_bw(), # Change ggplot2 theme
#palette = c("#E7B800", "#2E9FDF"),
xlab="Time (months)", ylab = "Overall survival",
xlim = c(0,72), break.x.by = c(12),
ylim = c(0,1), break.y.by = c(0.25),
legend.labs = c("HCT <3", "HCT \u22653"),
legend = "none",
surv.scale="percent",
font.main = c(16, "plain", "black"),
font.x = c(16, "plain", "black"),
font.y = c(16, "plain", "black"),
font.caption = c(16, "plain", "black"),
font.tickslab = c(16, "plain", "black")
)
OS_plot

Create KM for OS stratified by bridging response category
Show code
data1 = dataset %>%
mutate(
Bridging.response.category = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD"), levels = c("No bridging","CR/PR","SD/PD"))
)
km_OS <- survfit(Surv(Days.to.DLC/30, Death) ~ Bridging.response.category, data1 )
km_OS
Call: survfit(formula = Surv(Days.to.DLC/30, Death) ~ Bridging.response.category,
data = data1)
4 observations deleted due to missingness
n events median 0.95LCL
Bridging.response.category=No bridging 88 32 43.97 16.00
Bridging.response.category=CR/PR 21 9 13.57 7.07
Bridging.response.category=SD/PD 36 23 6.53 4.70
0.95UCL
Bridging.response.category=No bridging NA
Bridging.response.category=CR/PR NA
Bridging.response.category=SD/PD 13.6
Show code
OS_plot <- ggsurvplot(km_OS,
pval=TRUE,
conf.int = TRUE,
risk.table = TRUE, # Add risk table
fontsize = 6,
risk.table.col = "strata", # Change risk table color by groups
tables.height = 0.25,
tables.theme = theme_cleantable(),
#surv.median.line = "hv", # Specify median survival
#ggtheme = theme_bw(), # Change ggplot2 theme
#palette = c("#E7B800", "#2E9FDF"),
xlab="Time (months)", ylab = "Overall survival",
xlim = c(0,72), break.x.by = c(12),
ylim = c(0,1), break.y.by = c(0.25),
legend.labs = c("No bridging","CR/PR","SD/PD"),
legend = "none",
surv.scale="percent",
font.main = c(16, "plain", "black"),
font.x = c(16, "plain", "black"),
font.y = c(16, "plain", "black"),
font.caption = c(16, "plain", "black"),
font.tickslab = c(16, "plain", "black")
)
OS_plot

Create KM for PFS stratified by best response
Show code
km_PFS <- survfit(Surv(Days.to.relapse.death.or.DLC/30, Relapse.or.death) ~ Best.response, data = filter(dataset, Infused == 1 & Best.response != "SD"& Best.response != "PD") )
km_PFS
Call: survfit(formula = Surv(Days.to.relapse.death.or.DLC/30, Relapse.or.death) ~
Best.response, data = filter(dataset, Infused == 1 & Best.response !=
"SD" & Best.response != "PD"))
n events median 0.95LCL 0.95UCL
Best.response=CR 77 27 NA 22.57 NA
Best.response=PR 39 24 4.07 3.47 19.6
Show code
#autoplot(km_Regain)
PFS_plot <- ggsurvplot(km_PFS,
pval=TRUE,
conf.int = TRUE,
risk.table = TRUE, # Add risk table
fontsize = 6,
risk.table.col = "strata", # Change risk table color by groups
tables.height = 0.25,
tables.theme = theme_cleantable(),
#surv.median.line = "hv", # Specify median survival
#ggtheme = theme_bw(), # Change ggplot2 theme
#palette = c("#E7B800", "#2E9FDF"),
xlab="Time (months)", ylab = "Progression-free survival",
xlim = c(0,72), break.x.by = c(12),
ylim = c(0,1), break.y.by = c(0.25),
legend.labs = c("CR", "PR"),
legend = "none",
surv.scale="percent",
font.main = c(16, "plain", "black"),
font.x = c(16, "plain", "black"),
font.y = c(16, "plain", "black"),
font.caption = c(16, "plain", "black"),
font.tickslab = c(16, "plain", "black")
)
PFS_plot

Create KM for PFS stratified by Bulky disease (>=5cm) status
Show code
km_PFS <- survfit(Surv(Days.to.relapse.death.or.DLC/30, Relapse.or.death) ~ Bulky, data = filter(dataset, Infused == 1 | Best.response != "") )
km_PFS
Call: survfit(formula = Surv(Days.to.relapse.death.or.DLC/30, Relapse.or.death) ~
Bulky, data = filter(dataset, Infused == 1 | Best.response !=
""))
n events median 0.95LCL 0.95UCL
Bulky=0 105 55 11.90 6.77 44
Bulky=1 44 29 3.63 1.47 22
Show code
#autoplot(km_Regain)
PFS_plot <- ggsurvplot(km_PFS,
pval=TRUE,
conf.int = TRUE,
risk.table = TRUE, # Add risk table
fontsize = 6,
risk.table.col = "strata", # Change risk table color by groups
tables.height = 0.25,
tables.theme = theme_cleantable(),
xlab="Time (months)", ylab = "Progression-free survival",
xlim = c(0,72), break.x.by = c(12),
ylim = c(0,1), break.y.by = c(0.25),
legend.labs = c("Non-bulky","Bulky"),
legend = "none",
surv.scale="percent",
font.main = c(16, "plain", "black"),
font.x = c(16, "plain", "black"),
font.y = c(16, "plain", "black"),
font.caption = c(16, "plain", "black"),
font.tickslab = c(16, "plain", "black")
)
PFS_plot

Create KM for PFS stratified by Breyanzi out-of-spec (EAP) status
Show code
km_PFS <- survfit(Surv(Days.to.DLC/30, Relapse.or.death) ~ EAP, data = filter(dataset, CAR.T.Product.Type == "Breyanzi") )
km_PFS
Call: survfit(formula = Surv(Days.to.DLC/30, Relapse.or.death) ~ EAP,
data = filter(dataset, CAR.T.Product.Type == "Breyanzi"))
n events median 0.95LCL 0.95UCL
EAP=0 39 22 13.2 8.67 25.5
EAP=1 11 8 24.5 8.40 NA
Show code
PFS_plot <- ggsurvplot(km_PFS,
pval=TRUE,
conf.int = TRUE,
risk.table = TRUE, # Add risk table
fontsize = 6,
risk.table.col = "strata", # Change risk table color by groups
tables.height = 0.25,
tables.theme = theme_cleantable(),
xlab="Time (months)", ylab = "Progression-free survival",
xlim = c(0,72), break.x.by = c(12),
ylim = c(0,1), break.y.by = c(0.25),
legend.labs = c("In-spec", "Out-of-spec"),
legend = "none",
surv.scale="percent",
font.main = c(16, "plain", "black"),
font.x = c(16, "plain", "black"),
font.y = c(16, "plain", "black"),
font.caption = c(16, "plain", "black"),
font.tickslab = c(16, "plain", "black")
)
PFS_plot

Create KM for PFS stratified by LDH status (<210 vs >=210 U/L)
Show code
data1 = filter(dataset, Infused == 1)
km_PFS <- survfit(Surv(Days.to.relapse.death.or.DLC/30, Relapse.or.death) ~ High.LDH, data1)
km_PFS
Call: survfit(formula = Surv(Days.to.relapse.death.or.DLC/30, Relapse.or.death) ~
High.LDH, data = data1)
1 observation deleted due to missingness
n events median 0.95LCL 0.95UCL
High.LDH=0 84 44 19.17 7.20 47.5
High.LDH=1 64 39 3.63 2.83 10.9
Show code
#autoplot(km_Regain)
PFS_plot <- ggsurvplot(km_PFS,
pval=TRUE,
conf.int = TRUE,
risk.table = TRUE, # Add risk table
fontsize = 6,
risk.table.col = "strata", # Change risk table color by groups
tables.height = 0.25,
tables.theme = theme_cleantable(),
#surv.median.line = "hv", # Specify median survival
#ggtheme = theme_bw(), # Change ggplot2 theme
#palette = c("#E7B800", "#2E9FDF"),
xlab="Time (months)", ylab = "Progression-free survival",
xlim = c(0,72), break.x.by = c(12),
ylim = c(0,1), break.y.by = c(0.25),
legend.labs = c("LDH <210 U/L", "LDH \u2265210 U/L"),
legend = "none",
surv.scale="percent",
font.main = c(16, "plain", "black"),
font.x = c(16, "plain", "black"),
font.y = c(16, "plain", "black"),
font.caption = c(16, "plain", "black"),
font.tickslab = c(16, "plain", "black")
)
PFS_plot

Create KM for PFS stratified by HCT-CI status (>=3 vs <3)
Show code
data1 = filter(dataset, Infused == 1) %>%
mutate(
High.HCT.CI = ifelse(HCT.CI >=3,1,0) )
km_PFS <- survfit(Surv(Days.to.relapse.death.or.DLC/30, Relapse.or.death) ~ High.HCT.CI, data1 )
km_PFS
Call: survfit(formula = Surv(Days.to.relapse.death.or.DLC/30, Relapse.or.death) ~
High.HCT.CI, data = data1)
n events median 0.95LCL 0.95UCL
High.HCT.CI=0 100 53 7.43 4.67 24.3
High.HCT.CI=1 49 31 6.07 3.27 41.1
Show code
PFS_plot <- ggsurvplot(km_PFS,
pval=TRUE,
conf.int = TRUE,
risk.table = TRUE, # Add risk table
fontsize = 6,
risk.table.col = "strata", # Change risk table color by groups
tables.height = 0.25,
tables.theme = theme_cleantable(),
#surv.median.line = "hv", # Specify median survival
#ggtheme = theme_bw(), # Change ggplot2 theme
#palette = c("#E7B800", "#2E9FDF"),
xlab="Time (months)", ylab = "Progression-free survival",
xlim = c(0,72), break.x.by = c(12),
ylim = c(0,1), break.y.by = c(0.25),
legend.labs = c("HCT <3", "HCT \u22653"),
legend = "none",
surv.scale="percent",
font.main = c(16, "plain", "black"),
font.x = c(16, "plain", "black"),
font.y = c(16, "plain", "black"),
font.caption = c(16, "plain", "black"),
font.tickslab = c(16, "plain", "black")
)
PFS_plot

Create KM for PFS stratified by bridging response category
Show code
data1 = dataset %>%
mutate(
Bridging.response.category = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD"), levels = c("No bridging","CR/PR","SD/PD"))
)
km_PFS <- survfit(Surv(Days.to.relapse.death.or.DLC/30, Relapse.or.death) ~ Bridging.response.category, data1 )
km_PFS
Call: survfit(formula = Surv(Days.to.relapse.death.or.DLC/30, Relapse.or.death) ~
Bridging.response.category, data = data1)
4 observations deleted due to missingness
n events median 0.95LCL
Bridging.response.category=No bridging 88 40 39.77 10.33
Bridging.response.category=CR/PR 21 12 7.43 3.67
Bridging.response.category=SD/PD 36 28 3.23 2.23
0.95UCL
Bridging.response.category=No bridging NA
Bridging.response.category=CR/PR NA
Bridging.response.category=SD/PD 7.17
Show code
PFS_plot <- ggsurvplot(km_PFS,
pval=TRUE,
conf.int = TRUE,
risk.table = TRUE, # Add risk table
fontsize = 6,
risk.table.col = "strata", # Change risk table color by groups
tables.height = 0.3,
tables.theme = theme_cleantable(),
#surv.median.line = "hv", # Specify median survival
#ggtheme = theme_bw(), # Change ggplot2 theme
#palette = c("#E7B800", "#2E9FDF"),
xlab="Time (months)", ylab = "Progression-free survival",
xlim = c(0,72), break.x.by = c(12),
ylim = c(0,1), break.y.by = c(0.25),
legend.labs = c("No bridging","CR/PR","SD/PD"),
legend = "none",
surv.scale="percent",
font.main = c(16, "plain", "black"),
font.x = c(16, "plain", "black"),
font.y = c(16, "plain", "black"),
font.caption = c(16, "plain", "black"),
font.tickslab = c(16, "plain", "black")
)
PFS_plot

WEIGHTED KM PLOTS
Create weighted KM for OS
Show code
data1 = IPTW.data
km_OS <- survfit(Surv(Days.to.DLC/30, Death) ~ CAR.T.Product.Type, data1, weights=weights)
km_OS
Call: survfit(formula = Surv(Days.to.DLC/30, Death) ~ CAR.T.Product.Type,
data = data1, weights = weights)
records n events median 0.95LCL
CAR.T.Product.Type=Breyanzi 50 40.6 17.3 15.6 11.90
CAR.T.Product.Type=Yescarta 99 86.1 40.3 16.3 8.97
0.95UCL
CAR.T.Product.Type=Breyanzi NA
CAR.T.Product.Type=Yescarta NA
Show code
med_OS <- surv_median(km_OS)
p.logrank <- survdiff(Surv(Days.to.DLC/30, Death) ~ CAR.T.Product.Type, data1)$pvalue
oneYr <- summary(km_OS,times=c(12))
oneYr
Call: survfit(formula = Surv(Days.to.DLC/30, Death) ~ CAR.T.Product.Type,
data = data1, weights = weights)
CAR.T.Product.Type=Breyanzi
time n.risk n.event survival std.err
12.0000 16.0336 13.7107 0.6008 0.0883
lower 95% CI upper 95% CI
0.4504 0.8013
CAR.T.Product.Type=Yescarta
time n.risk n.event survival std.err
12.000 36.110 30.479 0.555 0.061
lower 95% CI upper 95% CI
0.447 0.689
Show code
oneYr$surv[1]- oneYr$surv[2] # Difference in survival at 1 yr for Breyanzi vs Yescarta
[1] 0.04569224
Show code
print("Difference in survival: ")
[1] "Difference in survival: "
Show code
diffSE <- sqrt(oneYr$std.err[2]^2 + oneYr$std.err[1]^2) # calculate the standard error
#Calculate the 95% CI for the difference
print("95% CI: ")
[1] "95% CI: "
Show code
oneYr$surv[1] - oneYr$surv[2] - 1.96 * diffSE
[1] -0.1646864
Show code
oneYr$surv[1] - oneYr$surv[2] + 1.96 * diffSE
[1] 0.2560708
Show code
zStat <- (oneYr$surv[1] - oneYr$surv[2])/diffSE # calculate the c-test statistic
print("p-value: ")
[1] "p-value: "
Show code
p = 2 * pnorm(abs(zStat), lower.tail = FALSE) # calculate a two-sided p-value
#autoplot(km_Regain)
OS_plot <- ggsurvplot(km_OS,
pval=FALSE,
conf.int = TRUE,
risk.table = TRUE, # Add risk table
fontsize = 6,
risk.table.col = "strata", # Change risk table color by groups
tables.height = 0.25,
tables.theme = theme_cleantable(),
xlab="Time (months)", ylab = "Overall survival",
xlim = c(0,36), break.x.by = c(180/30),
ylim = c(0,1), break.y.by = c(0.25),
legend.labs = c("Liso-cel","Axi-cel"),
legend = "none",
surv.scale="percent",
font.main = c(16, "plain", "black"),
font.x = c(16, "plain", "black"),
font.y = c(16, "plain", "black"),
font.caption = c(16, "plain", "black"),
font.tickslab = c(16, "plain", "black")
)
OS_plot$plot <- OS_plot$plot +
geom_vline(xintercept = 12, linetype = "dashed", color = "steelblue") +
geom_hline(yintercept = 0.5, linetype = "dashed", color = "black") +
annotate("text", x = 12.5, y = 0.83, label = paste("Liso-cel vs axi-cel: 1-year OS\n", signif(oneYr$surv[1]*100, 2), "% vs ", signif(oneYr$surv[2]*100, 2), "%, p =", signif(p,2)), color = "steelblue", hjust = 0, vjust = -0.5, size = 3) +
annotate("text", x = 13, y = 0, label = paste("Liso-cel vs axi-cel,\nmedian OS:\n", signif(med_OS$median[1], 2), "vs", signif(med_OS$median[2], 2), "months, p =", signif(p.logrank,2)), color = "black", hjust = 0, vjust = -0.5, size = 3, fontface = "bold")
OS_plot

Create weighted KM for PFS, stratified by product
Show code
data1 = IPTW.data
km_RFS <- survfit(Surv(Days.to.relapse.death.or.DLC/30, Relapse.or.death) ~ CAR.T.Product.Type, data = data1, weights=weights )
km_RFS
Call: survfit(formula = Surv(Days.to.relapse.death.or.DLC/30, Relapse.or.death) ~
CAR.T.Product.Type, data = data1, weights = weights)
records n events median 0.95LCL
CAR.T.Product.Type=Breyanzi 50 40.6 23.1 7.43 4.67
CAR.T.Product.Type=Yescarta 99 86.1 46.6 10.33 4.90
0.95UCL
CAR.T.Product.Type=Breyanzi NA
CAR.T.Product.Type=Yescarta 47.5
Show code
med_RFS <- surv_median(km_RFS)
p.logrank <- survdiff(Surv(Days.to.relapse.death.or.DLC/30, Relapse.or.death) ~ CAR.T.Product.Type, data1)$pvalue
oneYr <- summary(km_RFS,times=c(12))
oneYr
Call: survfit(formula = Surv(Days.to.relapse.death.or.DLC/30, Relapse.or.death) ~
CAR.T.Product.Type, data = data1, weights = weights)
CAR.T.Product.Type=Breyanzi
time n.risk n.event survival std.err
12.0000 9.6155 20.9003 0.3951 0.0873
lower 95% CI upper 95% CI
0.2562 0.6092
CAR.T.Product.Type=Yescarta
time n.risk n.event survival std.err
12.0000 30.4878 39.6663 0.4697 0.0597
lower 95% CI upper 95% CI
0.3662 0.6025
Show code
oneYr$surv[1]- oneYr$surv[2] # Difference in survival at 1 yr for Breyanzi vs Yescarta
[1] -0.07463201
Show code
print("Difference in survival: ")
[1] "Difference in survival: "
Show code
diffSE <- sqrt(oneYr$std.err[2]^2 + oneYr$std.err[1]^2) # calculate the standard error
#Calculate the 95% CI for the difference
print("95% CI: ")
[1] "95% CI: "
Show code
oneYr$surv[1] - oneYr$surv[2] - 1.96 * diffSE
[1] -0.281858
Show code
oneYr$surv[1] - oneYr$surv[2] + 1.96 * diffSE
[1] 0.132594
Show code
zStat <- (oneYr$surv[1] - oneYr$surv[2])/diffSE # calculate the c-test statistic
print("p-value: ")
[1] "p-value: "
Show code
p = 2 * pnorm(abs(zStat), lower.tail = FALSE) # calculate a two-sided p-value
#autoplot(km_Regain)
RFS_plot <- ggsurvplot(km_RFS,
pval=FALSE,
conf.int = TRUE,
risk.table = TRUE, # Add risk table
fontsize = 6,
risk.table.col = "strata", # Change risk table color by groups
tables.height = 0.25,
tables.theme = theme_cleantable(),
xlab="Time (months)", ylab = "Progression-free survival",
xlim = c(0,36), break.x.by = c(180/30),
ylim = c(0,1), break.y.by = c(0.25),
legend.labs = c("Liso-cel","Axi-cel"),
legend = "none",
surv.scale="percent",
font.main = c(16, "plain", "black"),
font.x = c(16, "plain", "black"),
font.y = c(16, "plain", "black"),
font.caption = c(16, "plain", "black"),
font.tickslab = c(16, "plain", "black")
)
RFS_plot$plot <- RFS_plot$plot +
geom_vline(xintercept = 12, linetype = "dashed", color = "steelblue") +
geom_hline(yintercept = 0.5, linetype = "dashed", color = "black") +
annotate("text", x = 12.5, y = 0.83, label = paste("Liso-cel vs axi-cel: 1-year PFS\n", signif(oneYr$surv[1]*100, 2), "% vs ", signif(oneYr$surv[2]*100, 2), "%, p =", signif(p,2)), color = "steelblue", hjust = 0, vjust = -0.5, size = 3) +
annotate("text", x = 13, y = .55, label = paste("Liso-cel vs axi-cel,\nmedian PFS:\n", signif(med_RFS$median[1], 2), "vs", signif(med_RFS$median[2], 2), "months, p =", signif(p.logrank,2)), color = "black", hjust = 0, vjust = -0.5, size = 3, fontface = "bold")
RFS_plot

REGRESSION ANALYSIS: UNWEIGHTED AND IPTW
PFS/OS
Cox Model - PFS
Show code
theme_gtsummary_compact()
preds <- c("Product", "LDH pre-LD", "ALC pre-LD","Largest lesion", "Age", "Male sex", "Bridging category")
data0 <- dataset %>%
mutate(
"Male sex" = ifelse(Sex == "M",1,0),
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
"ALC pre-LD" = ALC.preLD,
"LDH pre-LD" = LDH.preLD/1000,
"Largest lesion" = Largest.lesion,
"Bridging category" = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD"), levels = c("No bridging","CR/PR","SD/PD"))
)
data1 <- IPTW.data %>%
mutate(
"Male sex" = ifelse(Sex == "M",1,0),
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
"ALC pre-LD" = ALC.preLD,
"LDH pre-LD" = LDH.preLD/1000,
"Largest lesion" = Largest.lesion,
"Bridging category" = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD"), levels = c("No bridging","CR/PR","SD/PD")),
)
data2 <- m.data %>%
mutate(
"Male sex" = ifelse(Sex == "M",1,0),
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
"ALC pre-LD" = ALC.preLD,
"LDH pre-LD" = LDH.preLD/1000,
"Largest lesion" = Largest.lesion,
"Bridging category" = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD"), levels = c("No bridging","CR/PR","SD/PD")),
)
uv_tab <- tbl_uvregression(
data0[c(preds)],
method = coxph,
y = Surv(data0$Days.to.relapse.death.or.DLC, data0$Relapse.or.death),
exponentiate = TRUE
)
mv_tab<-coxph( Surv(Days.to.relapse.death.or.DLC, Relapse.or.death) ~ Product + `LDH pre-LD`+ `ALC pre-LD` + `Largest lesion` + Age+ `Male sex` + `Bridging category`, data0) %>% tbl_regression(exponentiate=TRUE)
uv_tab_IPTW <- tbl_uvregression(
data1[c(preds)],
method = coxph,
y = Surv(data1$Days.to.relapse.death.or.DLC, data1$Relapse.or.death),
exponentiate = TRUE,
method.args = list(weights = data1$weights),
)
mv_tab_IPTW<-coxph( Surv(Days.to.relapse.death.or.DLC, Relapse.or.death) ~ Product + `LDH pre-LD`+ `ALC pre-LD` + `Largest lesion` + Age + `Male sex` + `Bridging category`, data1, weights=weights) %>%tbl_regression( exponentiate=TRUE)
uv_tab_PSM <- tbl_uvregression(
data2[c(preds)],
method = coxph,
y = Surv(data2$Days.to.relapse.death.or.DLC, data2$Relapse.or.death),
exponentiate = TRUE,
method.args = list(weights = data2$weights),
)
mv_tab_PSM<-coxph( Surv(Days.to.relapse.death.or.DLC, Relapse.or.death) ~ Product + `LDH pre-LD`+ `ALC pre-LD` + `Largest lesion` + Age + `Male sex` + `Bridging category`, data2, weights=weights) %>%tbl_regression( exponentiate=TRUE)
row1 <- tbl_merge(list(uv_tab, mv_tab), tab_spanner = c("**Univariate**", "**Multivariable**"))
row2 <- tbl_merge(list(uv_tab_IPTW, mv_tab_IPTW))
row3 <- tbl_merge(list(uv_tab_PSM, mv_tab_PSM))
tbl_stack(list(row1, row2, row3), group_header = c("UNWEIGHTED ANALYSIS", "IPTW ANALYSIS", "PSM ANALYSIS"), quiet=TRUE)
| Characteristic |
Univariate
|
Multivariable
|
| N |
HR |
95% CI |
p-value |
HR |
95% CI |
p-value |
| UNWEIGHTED ANALYSIS |
| Product |
149 |
|
|
|
|
|
|
| Liso-cel |
|
— |
— |
|
— |
— |
|
| Axi-cel |
|
0.85 |
0.54, 1.34 |
0.5 |
0.93 |
0.56, 1.54 |
0.8 |
| LDH pre-LD |
148 |
1.14 |
1.01, 1.28 |
0.037 |
1.10 |
0.96, 1.26 |
0.2 |
| ALC pre-LD |
149 |
1.11 |
0.96, 1.29 |
0.2 |
1.11 |
0.99, 1.25 |
0.069 |
| Largest lesion |
149 |
1.08 |
1.02, 1.14 |
0.011 |
1.05 |
0.98, 1.12 |
0.2 |
| Age |
149 |
1.0 |
0.98, 1.01 |
0.5 |
1.00 |
0.98, 1.02 |
0.7 |
| Male sex |
149 |
1.05 |
0.67, 1.64 |
0.8 |
1.28 |
0.78, 2.09 |
0.3 |
| Bridging category |
145 |
|
|
|
|
|
|
| No bridging |
|
— |
— |
|
— |
— |
|
| CR/PR |
|
1.58 |
0.83, 3.04 |
0.2 |
1.69 |
0.86, 3.32 |
0.13 |
| SD/PD |
|
2.68 |
1.63, 4.39 |
<0.001 |
2.31 |
1.29, 4.13 |
0.005 |
| IPTW ANALYSIS |
| Product |
126 |
|
|
|
|
|
|
| Liso-cel |
|
— |
— |
|
— |
— |
|
| Axi-cel |
|
0.90 |
0.56, 1.46 |
0.7 |
1.07 |
0.64, 1.79 |
0.8 |
| LDH pre-LD |
125 |
1.14 |
1.08, 1.21 |
<0.001 |
1.11 |
1.04, 1.18 |
0.001 |
| ALC pre-LD |
126 |
1.12 |
0.96, 1.31 |
0.15 |
1.13 |
1.05, 1.21 |
0.001 |
| Largest lesion |
126 |
1.05 |
0.99, 1.12 |
0.11 |
1.01 |
0.94, 1.09 |
0.7 |
| Age |
126 |
1.00 |
0.98, 1.02 |
0.8 |
1.00 |
0.98, 1.02 |
0.8 |
| Male sex |
126 |
1.03 |
0.63, 1.69 |
0.9 |
1.29 |
0.74, 2.25 |
0.4 |
| Bridging category |
123 |
|
|
|
|
|
|
| No bridging |
|
— |
— |
|
— |
— |
|
| CR/PR |
|
1.61 |
0.69, 3.74 |
0.3 |
1.71 |
0.67, 4.33 |
0.3 |
| SD/PD |
|
2.62 |
1.60, 4.29 |
<0.001 |
2.60 |
1.44, 4.71 |
0.002 |
| PSM ANALYSIS |
| Product |
149 |
|
|
|
|
|
|
| Liso-cel |
|
— |
— |
|
— |
— |
|
| Axi-cel |
|
0.79 |
0.45, 1.39 |
0.4 |
0.87 |
0.50, 1.52 |
0.6 |
| LDH pre-LD |
148 |
1.23 |
1.09, 1.39 |
<0.001 |
1.19 |
1.06, 1.33 |
0.003 |
| ALC pre-LD |
149 |
1.16 |
1.07, 1.26 |
<0.001 |
1.15 |
1.09, 1.22 |
<0.001 |
| Largest lesion |
149 |
1.05 |
0.98, 1.13 |
0.2 |
0.99 |
0.92, 1.06 |
0.8 |
| Age |
149 |
0.99 |
0.97, 1.01 |
0.5 |
1.01 |
0.98, 1.03 |
0.6 |
| Male sex |
149 |
1.46 |
0.80, 2.67 |
0.2 |
1.71 |
0.99, 2.94 |
0.052 |
| Bridging category |
144 |
|
|
|
|
|
|
| No bridging |
|
— |
— |
|
— |
— |
|
| CR/PR |
|
1.04 |
0.32, 3.37 |
>0.9 |
1.02 |
0.31, 3.35 |
>0.9 |
| SD/PD |
|
2.77 |
1.59, 4.81 |
<0.001 |
2.86 |
1.62, 5.07 |
<0.001 |
Cox Model - PFS forest plots
Show code
## Forest plot for MV
df_fp <- mv_tab$table_body %>%
select(header_row, label, N_obs, N_event, estimate, conf.low, conf.high, p.value, ) %>%
mutate(
label = ifelse(header_row == TRUE | is.na(header_row),as.character(label), paste0(" ", as.character(label)) ),
p.value = signif(p.value, 2),
`HR (95% CI)` = ifelse(
is.na(estimate),"",paste0(round(estimate, 2), " (", round(conf.low,2), " to ",round(conf.high,2), ") ")
)
) %>%
rename(Characteristic = label,
N = N_obs,
Events = N_event,
`p value` = p.value)
forester(
left_side_data = df_fp[2],
right_side_data = df_fp[9:8],
estimate = df_fp$estimate,
ci_low = df_fp$conf.low,
ci_high = df_fp$conf.high,
estimate_col_name = "HR (95% CI)",
xlim = c(0.1, 10),
null_line_at = 1,
arrows = TRUE,
x_scale_linear = FALSE,
arrow_labels = c("Better", "Worse"),
font_family = "sans",
display = TRUE,
nudge_x = .4,
nudge_height = .06,
stripe_colour = "#F5F5F5",
file_path = "/Users/aportugu/Desktop/CD19 project/ASH abstract/forest/PFS_mv_plot.png"
)
knitr::include_graphics("/Users/aportugu/Desktop/CD19 project/ASH abstract/forest/PFS_mv_plot.png")
Show code
## Forest plot for MV IPTW
df_fp <- mv_tab_IPTW$table_body %>%
select(header_row, label, N_obs, N_event, estimate, conf.low, conf.high, p.value, ) %>%
mutate(
label = ifelse(header_row == TRUE | is.na(header_row),as.character(label), paste0(" ", as.character(label)) ),
p.value = signif(p.value, 2),
`HR (95% CI)` = ifelse(
is.na(estimate),"",paste0(round(estimate, 2), " (", round(conf.low,2), " to ",round(conf.high,2), ") ")
)
) %>%
rename(Characteristic = label,
N = N_obs,
Events = N_event,
`p value` = p.value)
forester(
left_side_data = df_fp[2],
right_side_data = df_fp[9:8],
estimate = df_fp$estimate,
ci_low = df_fp$conf.low,
ci_high = df_fp$conf.high,
estimate_col_name = "HR (95% CI)",
xlim = c(0.1, 10),
null_line_at = 1,
arrows = TRUE,
x_scale_linear = FALSE,
arrow_labels = c("Better", "Worse"),
font_family = "sans",
display = TRUE,
nudge_x = .4,
nudge_height = .06,
stripe_colour = "#F5F5F5",
file_path = "/Users/aportugu/Desktop/CD19 project/ASH abstract/forest/PFS_mv_plot_IPTW.png"
)
knitr::include_graphics("/Users/aportugu/Desktop/CD19 project/ASH abstract/forest/PFS_mv_plot_IPTW.png")
Show code
## Forest plot for MV PSM
df_fp <- mv_tab_PSM$table_body %>%
select(header_row, label, N_obs, N_event, estimate, conf.low, conf.high, p.value, ) %>%
mutate(
label = ifelse(header_row == TRUE | is.na(header_row),as.character(label), paste0(" ", as.character(label)) ),
p.value = signif(p.value, 2),
`HR (95% CI)` = ifelse(
is.na(estimate),"",paste0(round(estimate, 2), " (", round(conf.low,2), " to ",round(conf.high,2), ") ")
)
) %>%
rename(Characteristic = label,
N = N_obs,
Events = N_event,
`p value` = p.value)
forester(
left_side_data = df_fp[2],
right_side_data = df_fp[9:8],
estimate = df_fp$estimate,
ci_low = df_fp$conf.low,
ci_high = df_fp$conf.high,
estimate_col_name = "HR (95% CI)",
xlim = c(0.1, 10),
null_line_at = 1,
arrows = TRUE,
x_scale_linear = FALSE,
arrow_labels = c("Better", "Worse"),
font_family = "sans",
display = TRUE,
nudge_x = .4,
nudge_height = .06,
stripe_colour = "#F5F5F5",
file_path = "/Users/aportugu/Desktop/CD19 project/ASH abstract/forest/PFS_mv_plot_PSM.png"
)
knitr::include_graphics("/Users/aportugu/Desktop/CD19 project/ASH abstract/forest/PFS_mv_plot_PSM.png")

Cox Model - OS
Show code
theme_gtsummary_compact()
preds <- c("Product","LDH pre-LD", "ALC pre-LD","Largest lesion", "Age", "Male sex", "Bridging category")
data0 <- dataset %>%
mutate(
"Male sex" = ifelse(Sex == "M",1,0),
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
"ALC pre-LD" = ALC.preLD,
"LDH pre-LD" = LDH.preLD/1000,
"Largest lesion" = Largest.lesion,
"Bridging category" = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD"), levels = c("No bridging","CR/PR","SD/PD"))
)
data1 <- IPTW.data %>%
mutate(
"Male sex" = ifelse(Sex == "M",1,0),
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
"ALC pre-LD" = ALC.preLD,
"LDH pre-LD" = LDH.preLD/1000,
"Largest lesion" = Largest.lesion,
"Bridging category" = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD"), levels = c("No bridging","CR/PR","SD/PD"))
)
data2 <- m.data %>%
mutate(
"Male sex" = ifelse(Sex == "M",1,0),
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
"ALC pre-LD" = ALC.preLD,
"LDH pre-LD" = LDH.preLD/1000,
"Largest lesion" = Largest.lesion,
"Bridging category" = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD"), levels = c("No bridging","CR/PR","SD/PD"))
)
uv_tab <- tbl_uvregression(
data0[c(preds)],
method = coxph,
y = Surv(data0$Days.to.DLC, data0$Death),
exponentiate = TRUE
)
mv_tab<-coxph( Surv(Days.to.DLC, Death) ~ Product +`LDH pre-LD` + `ALC pre-LD` + `Largest lesion` + Age + `Male sex` + `Bridging category`, data0) %>% tbl_regression(exponentiate=TRUE)
uv_tab_IPTW <- tbl_uvregression(
data1[c(preds)],
method = coxph,
y = Surv(data1$Days.to.DLC, data1$Death),
exponentiate = TRUE,
method.args = list(weights = data1$weights),
)
mv_tab_IPTW<-coxph( Surv(Days.to.DLC, Death) ~ Product +`LDH pre-LD` + `ALC pre-LD` + `Largest lesion` + Age + `Male sex` + `Bridging category`, data1, weights=weights) %>% tbl_regression(exponentiate=TRUE)
uv_tab_PSM <- tbl_uvregression(
data2[c(preds)],
method = coxph,
y = Surv(data2$Days.to.DLC, data2$Death),
exponentiate = TRUE,
method.args = list(weights = data2$weights),
)
mv_tab_PSM<-coxph( Surv(Days.to.DLC, Death) ~ Product +`LDH pre-LD` + `ALC pre-LD` + `Largest lesion` + Age + `Male sex` + `Bridging category`, data2, weights=weights) %>% tbl_regression(exponentiate=TRUE)
row1 <- tbl_merge(list(uv_tab, mv_tab), tab_spanner = c("**Univariate**", "**Multivariable**"))
row2 <- tbl_merge(list(uv_tab_IPTW, mv_tab_IPTW))
row3 <- tbl_merge(list(uv_tab_PSM, mv_tab_PSM))
tbl_stack(list(row1, row2, row3), group_header = c("UNWEIGHTED ANALYSIS", "IPTW ANALYSIS", "PSM ANALYSIS"), quiet=TRUE)
| Characteristic |
Univariate
|
Multivariable
|
| N |
HR |
95% CI |
p-value |
HR |
95% CI |
p-value |
| UNWEIGHTED ANALYSIS |
| Product |
149 |
|
|
|
|
|
|
| Liso-cel |
|
— |
— |
|
— |
— |
|
| Axi-cel |
|
1.19 |
0.69, 2.03 |
0.5 |
1.17 |
0.65, 2.13 |
0.6 |
| LDH pre-LD |
148 |
1.37 |
1.19, 1.58 |
<0.001 |
1.37 |
1.16, 1.61 |
<0.001 |
| ALC pre-LD |
149 |
1.23 |
1.04, 1.47 |
0.017 |
1.27 |
1.06, 1.52 |
0.010 |
| Largest lesion |
149 |
1.14 |
1.07, 1.21 |
<0.001 |
1.11 |
1.04, 1.19 |
0.002 |
| Age |
149 |
1.00 |
0.98, 1.02 |
0.7 |
1.00 |
0.98, 1.02 |
0.8 |
| Male sex |
149 |
1.12 |
0.66, 1.88 |
0.7 |
1.36 |
0.77, 2.39 |
0.3 |
| Bridging category |
145 |
|
|
|
|
|
|
| No bridging |
|
— |
— |
|
— |
— |
|
| CR/PR |
|
1.52 |
0.72, 3.21 |
0.3 |
1.85 |
0.85, 4.02 |
0.12 |
| SD/PD |
|
2.77 |
1.60, 4.78 |
<0.001 |
2.07 |
1.09, 3.93 |
0.026 |
| IPTW ANALYSIS |
| Product |
126 |
|
|
|
|
|
|
| Liso-cel |
|
— |
— |
|
— |
— |
|
| Axi-cel |
|
1.10 |
0.62, 1.95 |
0.7 |
1.17 |
0.63, 2.17 |
0.6 |
| LDH pre-LD |
125 |
1.36 |
1.22, 1.51 |
<0.001 |
1.34 |
1.20, 1.50 |
<0.001 |
| ALC pre-LD |
126 |
1.24 |
1.07, 1.44 |
0.005 |
1.28 |
1.17, 1.41 |
<0.001 |
| Largest lesion |
126 |
1.13 |
1.07, 1.20 |
<0.001 |
1.10 |
1.03, 1.18 |
0.003 |
| Age |
126 |
1.00 |
0.98, 1.02 |
0.8 |
1.00 |
0.97, 1.02 |
0.8 |
| Male sex |
126 |
1.06 |
0.60, 1.85 |
0.8 |
1.38 |
0.73, 2.61 |
0.3 |
| Bridging category |
123 |
|
|
|
|
|
|
| No bridging |
|
— |
— |
|
— |
— |
|
| CR/PR |
|
1.51 |
0.64, 3.53 |
0.3 |
1.74 |
0.68, 4.45 |
0.3 |
| SD/PD |
|
2.96 |
1.66, 5.27 |
<0.001 |
2.35 |
1.21, 4.59 |
0.012 |
| PSM ANALYSIS |
| Product |
149 |
|
|
|
|
|
|
| Liso-cel |
|
— |
— |
|
— |
— |
|
| Axi-cel |
|
1.06 |
0.56, 1.98 |
0.9 |
1.14 |
0.59, 2.21 |
0.7 |
| LDH pre-LD |
148 |
1.49 |
1.30, 1.72 |
<0.001 |
1.45 |
1.24, 1.71 |
<0.001 |
| ALC pre-LD |
149 |
1.33 |
1.21, 1.45 |
<0.001 |
1.38 |
1.12, 1.70 |
0.003 |
| Largest lesion |
149 |
1.14 |
1.07, 1.22 |
<0.001 |
1.09 |
1.01, 1.17 |
0.028 |
| Age |
149 |
1.00 |
0.96, 1.03 |
0.9 |
1.00 |
0.97, 1.05 |
0.8 |
| Male sex |
149 |
1.32 |
0.68, 2.59 |
0.4 |
1.26 |
0.66, 2.40 |
0.5 |
| Bridging category |
144 |
|
|
|
|
|
|
| No bridging |
|
— |
— |
|
— |
— |
|
| CR/PR |
|
1.29 |
0.40, 4.12 |
0.7 |
1.41 |
0.42, 4.72 |
0.6 |
| SD/PD |
|
3.15 |
1.56, 6.33 |
0.001 |
2.68 |
1.31, 5.48 |
0.007 |
Cox Model - OS forest plots
Show code
## Forest plot for MV
df_fp <- mv_tab$table_body %>%
select(header_row, label, N_obs, N_event, estimate, conf.low, conf.high, p.value, ) %>%
mutate(
label = ifelse(header_row == TRUE | is.na(header_row),as.character(label), paste0(" ", as.character(label)) ),
p.value = signif(p.value, 2),
`HR (95% CI)` = ifelse(
is.na(estimate),"",paste0(round(estimate, 2), " (", round(conf.low,2), " to ",round(conf.high,2), ") ")
)
) %>%
rename(Characteristic = label,
N = N_obs,
Events = N_event,
`p value` = p.value)
forester(
left_side_data = df_fp[2],
right_side_data = df_fp[9:8],
estimate = df_fp$estimate,
ci_low = df_fp$conf.low,
ci_high = df_fp$conf.high,
estimate_col_name = "HR (95% CI)",
xlim = c(0.1, 10),
null_line_at = 1,
arrows = TRUE,
x_scale_linear = FALSE,
arrow_labels = c("Better", "Worse"),
font_family = "sans",
display = TRUE,
nudge_x = .4,
nudge_height = .06,
stripe_colour = "#F5F5F5",
file_path = "/Users/aportugu/Desktop/CD19 project/ASH abstract/forest/OS_mv_plot.png"
)
knitr::include_graphics("/Users/aportugu/Desktop/CD19 project/ASH abstract/forest/OS_mv_plot.png")
Show code
## Forest plot for MV IPTW
df_fp <- mv_tab_IPTW$table_body %>%
select(header_row, label, N_obs, N_event, estimate, conf.low, conf.high, p.value, ) %>%
mutate(
label = ifelse(header_row == TRUE | is.na(header_row),as.character(label), paste0(" ", as.character(label)) ),
p.value = signif(p.value, 2),
`HR (95% CI)` = ifelse(
is.na(estimate),"",paste0(round(estimate, 2), " (", round(conf.low,2), " to ",round(conf.high,2), ") ")
)
) %>%
rename(Characteristic = label,
N = N_obs,
Events = N_event,
`p value` = p.value)
forester(
left_side_data = df_fp[2],
right_side_data = df_fp[9:8],
estimate = df_fp$estimate,
ci_low = df_fp$conf.low,
ci_high = df_fp$conf.high,
estimate_col_name = "HR (95% CI)",
xlim = c(0.1, 10),
null_line_at = 1,
arrows = TRUE,
x_scale_linear = FALSE,
arrow_labels = c("Better", "Worse"),
font_family = "sans",
display = TRUE,
nudge_x = .4,
nudge_height = .06,
stripe_colour = "#F5F5F5",
file_path = "/Users/aportugu/Desktop/CD19 project/ASH abstract/forest/OS_mv_plot_IPTW.png"
)
knitr::include_graphics("/Users/aportugu/Desktop/CD19 project/ASH abstract/forest/OS_mv_plot_IPTW.png")
Show code
## Forest plot for MV PSM
df_fp <- mv_tab_PSM$table_body %>%
select(header_row, label, N_obs, N_event, estimate, conf.low, conf.high, p.value, ) %>%
mutate(
label = ifelse(header_row == TRUE | is.na(header_row),as.character(label), paste0(" ", as.character(label)) ),
p.value = signif(p.value, 2),
`HR (95% CI)` = ifelse(
is.na(estimate),"",paste0(round(estimate, 2), " (", round(conf.low,2), " to ",round(conf.high,2), ") ")
)
) %>%
rename(Characteristic = label,
N = N_obs,
Events = N_event,
`p value` = p.value)
forester(
left_side_data = df_fp[2],
right_side_data = df_fp[9:8],
estimate = df_fp$estimate,
ci_low = df_fp$conf.low,
ci_high = df_fp$conf.high,
estimate_col_name = "HR (95% CI)",
xlim = c(0.1, 10),
null_line_at = 1,
arrows = TRUE,
x_scale_linear = FALSE,
arrow_labels = c("Better", "Worse"),
font_family = "sans",
display = TRUE,
nudge_x = .4,
nudge_height = .06,
stripe_colour = "#F5F5F5",
file_path = "/Users/aportugu/Desktop/CD19 project/ASH abstract/forest/OS_mv_plot_PSM.png"
)
knitr::include_graphics("/Users/aportugu/Desktop/CD19 project/ASH abstract/forest/OS_mv_plot_PSM.png")

Cox diagnostics
PFS unweighted
Show code
data1 <- dataset %>%
mutate(
ferritin.max = log(ferritin.max),
IL6.max = log(IL6.max),
LDH.min = log(LDH.min),
Age = Age,
`Male sex` = ifelse(Sex == "M",1,0),
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
`ALC pre-LD` = ALC.preLD,
`LDH pre-LD` = LDH.preLD/1000,
`High LDH pre-LD` = ifelse(LDH.preLD >=210,1,0),
`LDH day 0` = LDH.d0/1000,
`ALC day 0` = ALC.d0,
`Largest lesion` = Largest.lesion
)
res.cox <-coxph( Surv(Days.to.relapse.death.or.DLC, Relapse.or.death) ~ Product + `LDH pre-LD` + `ALC pre-LD` + `Largest lesion` + Age + `Male sex`, data1)
## Testing proportional hazards assumption
test.ph <- cox.zph(res.cox)
test.ph
chisq df p
Product 2.188 1 0.14
`LDH pre-LD` 2.538 1 0.11
`ALC pre-LD` 2.137 1 0.14
`Largest lesion` 1.293 1 0.26
Age 1.365 1 0.24
`Male sex` 0.215 1 0.64
GLOBAL 10.147 6 0.12
PFS IPTW
Show code
data1 <- IPTW.data %>%
mutate(
`Male sex` = ifelse(Sex == "M",1,0),
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
`ALC pre-LD` = ALC.preLD,
`LDH pre-LD` = LDH.preLD/1000,
`High LDH pre-LD` = ifelse(LDH.preLD >=210,1,0),
`LDH day 0` = LDH.d0/1000,
`ALC day 0` = ALC.d0,
`Largest lesion` = Largest.lesion
)
res.cox <-coxph( Surv(Days.to.relapse.death.or.DLC, Relapse.or.death) ~ Product + `LDH pre-LD` + `ALC pre-LD` + `Largest lesion`+ Age + `Male sex`, data1, weights=weights)
## Testing proportional hazards assumption
test.ph <- cox.zph(res.cox)
test.ph
chisq df p
Product 3.459 1 0.063
`LDH pre-LD` 2.039 1 0.153
`ALC pre-LD` 1.558 1 0.212
`Largest lesion` 0.370 1 0.543
Age 2.558 1 0.110
`Male sex` 0.179 1 0.672
GLOBAL 10.079 6 0.121
PFS PSM
Show code
data1 <- m.data %>%
mutate(
`Male sex` = ifelse(Sex == "M",1,0),
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
`ALC pre-LD` = ALC.preLD,
`LDH pre-LD` = LDH.preLD/1000,
`High LDH pre-LD` = ifelse(LDH.preLD >=210,1,0),
`LDH day 0` = LDH.d0/1000,
`ALC day 0` = ALC.d0,
`Largest lesion` = Largest.lesion
)
res.cox <-coxph( Surv(Days.to.relapse.death.or.DLC, Relapse.or.death) ~ Product + `LDH pre-LD` + `ALC pre-LD` + `Largest lesion`+ Age + `Male sex`, data1, weights=weights)
## Testing proportional hazards assumption
test.ph <- cox.zph(res.cox)
test.ph
chisq df p
Product 1.423 1 0.23
`LDH pre-LD` 0.991 1 0.32
`ALC pre-LD` 0.293 1 0.59
`Largest lesion` 0.338 1 0.56
Age 0.134 1 0.71
`Male sex` 1.066 1 0.30
GLOBAL 4.275 6 0.64
OS unweighted
Show code
data1 <- dataset %>%
mutate(
ferritin.max = log(ferritin.max),
IL6.max = log(IL6.max),
LDH.min = log(LDH.min),
Age = Age,
`Male sex` = ifelse(Sex == "M",1,0),
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
`ALC pre-LD` = ALC.preLD,
`LDH pre-LD` = LDH.preLD/1000,
`High LDH pre-LD` = ifelse(LDH.preLD >=210,1,0),
`LDH day 0` = LDH.d0/1000,
`ALC day 0` = ALC.d0,
`Largest lesion` = Largest.lesion
)
res.cox <-coxph( Surv(Days.to.DLC, Death) ~ Product + `LDH pre-LD` + `ALC pre-LD` + `Largest lesion`+ Age + `Male sex`, data1)
## Testing proportional hazards assumption
test.ph <- cox.zph(res.cox)
test.ph
chisq df p
Product 5.85230 1 0.016
`LDH pre-LD` 0.00569 1 0.940
`ALC pre-LD` 1.17243 1 0.279
`Largest lesion` 2.27721 1 0.131
Age 1.69047 1 0.194
`Male sex` 0.01424 1 0.905
GLOBAL 9.93558 6 0.127
OS IPTW
Show code
data1 <- IPTW.data %>%
mutate(
ferritin.max = log(ferritin.max),
IL6.max = log(IL6.max),
LDH.min = log(LDH.min),
Age = Age,
`Male sex` = ifelse(Sex == "M",1,0),
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
`ALC pre-LD` = ALC.preLD,
`LDH pre-LD` = LDH.preLD/1000,
`High LDH pre-LD` = ifelse(LDH.preLD >=210,1,0),
`LDH day 0` = LDH.d0/1000,
`ALC day 0` = ALC.d0,
`Largest lesion` = Largest.lesion
)
res.cox <-coxph( Surv(Days.to.DLC, Death) ~ Product + `LDH pre-LD` + `ALC pre-LD` + `Largest lesion`+ Age + `Male sex`, data1, weights=weights)
## Testing proportional hazards assumption
test.ph <- cox.zph(res.cox)
test.ph
chisq df p
Product 2.0630 1 0.15
`LDH pre-LD` 0.0402 1 0.84
`ALC pre-LD` 0.9209 1 0.34
`Largest lesion` 2.6437 1 0.10
Age 1.9744 1 0.16
`Male sex` 0.0519 1 0.82
GLOBAL 8.2084 6 0.22
OS PSM
Show code
data1 <- m.data %>%
mutate(
ferritin.max = log(ferritin.max),
IL6.max = log(IL6.max),
LDH.min = log(LDH.min),
Age = Age,
`Male sex` = ifelse(Sex == "M",1,0),
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
`ALC pre-LD` = ALC.preLD,
`LDH pre-LD` = LDH.preLD/1000,
`High LDH pre-LD` = ifelse(LDH.preLD >=210,1,0),
`LDH day 0` = LDH.d0/1000,
`ALC day 0` = ALC.d0,
`Largest lesion` = Largest.lesion
)
res.cox <-coxph( Surv(Days.to.DLC, Death) ~ Product + `LDH pre-LD` + `ALC pre-LD` + `Largest lesion`+ Age + `Male sex`, data1, weights=weights)
## Testing proportional hazards assumption
test.ph <- cox.zph(res.cox)
test.ph
chisq df p
Product 2.54e+00 1 0.111
`LDH pre-LD` 5.45e-01 1 0.460
`ALC pre-LD` 2.65e-06 1 0.999
`Largest lesion` 1.24e+00 1 0.266
Age 5.66e+00 1 0.017
`Male sex` 2.56e-01 1 0.613
GLOBAL 1.14e+01 6 0.076
Response
Logistic Model - CR
Show code
theme_gtsummary_compact()
preds <- c("Best.CR", "Product", "LDH pre-LD","ALC pre-LD", "Largest lesion", "Age", "Male sex", "Bridging category")
data0 <- dataset %>%
mutate(
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
"Largest lesion" = Largest.lesion,
"ALC pre-LD" = ALC.preLD,
"LDH pre-LD" = LDH.preLD/1000,
"Male sex" = ifelse(Sex == "M",1,0),
"Bridging category" = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD"), levels = c("No bridging","CR/PR","SD/PD"))
)
data1 <- IPTW.data %>%
mutate(
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
"Largest lesion" = Largest.lesion,
"ALC pre-LD" = ALC.preLD,
"LDH pre-LD" = LDH.preLD/1000,
"Male sex" = ifelse(Sex == "M",1,0),
"Bridging category" = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD"), levels = c("No bridging","CR/PR","SD/PD"))
)
data2 <- m.data %>%
mutate(
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
"Largest lesion" = Largest.lesion,
"ALC pre-LD" = ALC.preLD,
"LDH pre-LD" = LDH.preLD/1000,
"Male sex" = ifelse(Sex == "M",1,0),
"Bridging category" = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD"), levels = c("No bridging","CR/PR","SD/PD"))
)
uv_tab <- tbl_uvregression(
data0[c(preds)],
method = glm,
y = Best.CR,
method.args = list(family = binomial),
exponentiate = TRUE
)
mv_tab<-glm( Best.CR ~ `LDH pre-LD` + Product + `Largest lesion` + `ALC pre-LD` + `Age` + `Male sex` + `Bridging category`, data0, family = binomial ) %>%
tbl_regression(exponentiate=TRUE)
uv_tab_IPTW <- tbl_uvregression(
data1[c(preds)],
method = glm,
y = Best.CR,
method.args = list(family = binomial, weights = data1$weights),
exponentiate = TRUE
)
mv_tab_IPTW<-glm( Best.CR ~ `LDH pre-LD` +Product + `Largest lesion` + `ALC pre-LD` + `Age` + `Male sex` + `Bridging category`, data1, weights=weights, family = binomial ) %>%
tbl_regression(exponentiate=TRUE)
uv_tab_PSM <- tbl_uvregression(
data2[c(preds)],
method = glm,
y = Best.CR,
method.args = list(family = binomial, weights = data2$weights),
exponentiate = TRUE
)
mv_tab_PSM<-glm( Best.CR ~ `LDH pre-LD` +Product + `Largest lesion` + `ALC pre-LD` + `Age` + `Male sex` + `Bridging category`, data2, weights=weights, family = binomial ) %>%
tbl_regression(exponentiate=TRUE)
row1 <- tbl_merge(list(uv_tab, mv_tab), tab_spanner = c("**Univariate**", "**Multivariable**"))
row2 <- tbl_merge(list(uv_tab_IPTW, mv_tab_IPTW))
row3 <- tbl_merge(list(uv_tab_PSM, mv_tab_PSM))
tbl_stack(list(row1, row2, row3), group_header = c("UNWEIGHTED ANALYSIS", "IPTW ANALYSIS", "PSM ANALYSIS"), quiet=TRUE)
| Characteristic |
Univariate
|
Multivariable
|
| N |
OR |
95% CI |
p-value |
OR |
95% CI |
p-value |
| UNWEIGHTED ANALYSIS |
| Product |
149 |
|
|
|
|
|
|
| Liso-cel |
|
— |
— |
|
— |
— |
|
| Axi-cel |
|
0.68 |
0.34, 1.35 |
0.3 |
0.61 |
0.26, 1.38 |
0.2 |
| LDH pre-LD |
148 |
0.14 |
0.02, 0.60 |
0.022 |
0.22 |
0.03, 0.89 |
0.083 |
| ALC pre-LD |
149 |
0.98 |
0.78, 1.19 |
0.8 |
1.02 |
0.73, 1.25 |
0.8 |
| Largest lesion |
149 |
0.86 |
0.77, 0.95 |
0.005 |
0.90 |
0.80, 1.00 |
0.064 |
| Age |
149 |
1.00 |
0.98, 1.03 |
>0.9 |
0.99 |
0.96, 1.02 |
0.5 |
| Male sex |
149 |
0.79 |
0.40, 1.53 |
0.5 |
0.73 |
0.34, 1.53 |
0.4 |
| Bridging category |
145 |
|
|
|
|
|
|
| No bridging |
|
— |
— |
|
— |
— |
|
| CR/PR |
|
0.92 |
0.35, 2.48 |
0.9 |
0.79 |
0.28, 2.25 |
0.6 |
| SD/PD |
|
0.35 |
0.15, 0.77 |
0.011 |
0.51 |
0.20, 1.30 |
0.2 |
| IPTW ANALYSIS |
| Product |
126 |
|
|
|
|
|
|
| Liso-cel |
|
— |
— |
|
— |
— |
|
| Axi-cel |
|
0.65 |
0.30, 1.39 |
0.3 |
0.52 |
0.21, 1.21 |
0.14 |
| LDH pre-LD |
125 |
0.09 |
0.01, 0.52 |
0.022 |
0.12 |
0.01, 0.72 |
0.052 |
| ALC pre-LD |
126 |
0.96 |
0.71, 1.21 |
0.7 |
1.02 |
0.66, 1.30 |
0.9 |
| Largest lesion |
126 |
0.92 |
0.82, 1.01 |
0.091 |
0.96 |
0.86, 1.08 |
0.5 |
| Age |
126 |
1.00 |
0.97, 1.03 |
>0.9 |
0.99 |
0.96, 1.02 |
0.6 |
| Male sex |
126 |
0.99 |
0.47, 2.07 |
>0.9 |
0.85 |
0.37, 1.93 |
0.7 |
| Bridging category |
123 |
|
|
|
|
|
|
| No bridging |
|
— |
— |
|
— |
— |
|
| CR/PR |
|
0.69 |
0.25, 1.87 |
0.5 |
0.68 |
0.24, 1.98 |
0.5 |
| SD/PD |
|
0.34 |
0.14, 0.82 |
0.017 |
0.42 |
0.15, 1.17 |
0.10 |
| PSM ANALYSIS |
| Product |
149 |
|
|
|
|
|
|
| Liso-cel |
|
— |
— |
|
— |
— |
|
| Axi-cel |
|
1.11 |
0.55, 2.20 |
0.8 |
1.02 |
0.45, 2.30 |
>0.9 |
| LDH pre-LD |
148 |
0.06 |
0.00, 0.44 |
0.016 |
0.07 |
0.00, 0.68 |
0.044 |
| ALC pre-LD |
149 |
0.96 |
0.75, 1.17 |
0.7 |
1.02 |
0.72, 1.27 |
0.9 |
| Largest lesion |
149 |
0.90 |
0.81, 1.00 |
0.060 |
0.98 |
0.86, 1.10 |
0.7 |
| Age |
149 |
1.03 |
1.00, 1.07 |
0.071 |
1.02 |
0.97, 1.06 |
0.5 |
| Male sex |
149 |
0.39 |
0.18, 0.78 |
0.009 |
0.37 |
0.16, 0.80 |
0.014 |
| Bridging category |
144 |
|
|
|
|
|
|
| No bridging |
|
— |
— |
|
— |
— |
|
| CR/PR |
|
0.91 |
0.36, 2.40 |
0.8 |
1.20 |
0.44, 3.52 |
0.7 |
| SD/PD |
|
0.34 |
0.14, 0.81 |
0.015 |
0.70 |
0.24, 2.01 |
0.5 |
Logistic CR forest plots
Show code
## Forest plot for MV
df_fp <- mv_tab$table_body %>%
select(header_row, label, N_obs, N_event, estimate, conf.low, conf.high, p.value, ) %>%
mutate(
label = ifelse(header_row == TRUE | is.na(header_row),as.character(label), paste0(" ", as.character(label)) ),
p.value = signif(p.value, 2),
`OR (95% CI)` = ifelse(
is.na(estimate),"",paste0(round(estimate, 2), " (", round(conf.low,2), " to ",round(conf.high,2), ") ")
)
) %>%
rename(Characteristic = label,
N = N_obs,
Events = N_event,
`p value` = p.value)
forester(
left_side_data = df_fp[2],
right_side_data = df_fp[9:8],
estimate = df_fp$estimate,
ci_low = df_fp$conf.low,
ci_high = df_fp$conf.high,
estimate_col_name = "OR (95% CI)",
xlim = c(.05, 3),
null_line_at = 1,
arrows = TRUE,
x_scale_linear = FALSE,
arrow_labels = c("Worse", "Better"),
font_family = "sans",
display = TRUE,
nudge_x = .4,
nudge_height = .06,
stripe_colour = "#F5F5F5",
file_path = "/Users/aportugu/Desktop/CD19 project/ASH abstract/forest/CR_mv_plot.png"
)
knitr::include_graphics("/Users/aportugu/Desktop/CD19 project/ASH abstract/forest/CR_mv_plot.png")
Show code
## Forest plot for MV IPTW
df_fp <- mv_tab_IPTW$table_body %>%
select(header_row, label, N_obs, N_event, estimate, conf.low, conf.high, p.value, ) %>%
mutate(
label = ifelse(header_row == TRUE | is.na(header_row),as.character(label), paste0(" ", as.character(label)) ),
p.value = signif(p.value, 2),
`OR (95% CI)` = ifelse(
is.na(estimate),"",paste0(round(estimate, 2), " (", round(conf.low,2), " to ",round(conf.high,2), ") ")
)
) %>%
rename(Characteristic = label,
N = N_obs,
Events = N_event,
`p value` = p.value)
forester(
left_side_data = df_fp[2],
right_side_data = df_fp[9:8],
estimate = df_fp$estimate,
ci_low = df_fp$conf.low,
ci_high = df_fp$conf.high,
estimate_col_name = "OR (95% CI)",
xlim = c(.05, 3),
null_line_at = 1,
arrows = TRUE,
x_scale_linear = FALSE,
arrow_labels = c("Worse", "Better"),
font_family = "sans",
display = TRUE,
nudge_x = .4,
nudge_height = .06,
stripe_colour = "#F5F5F5",
file_path = "/Users/aportugu/Desktop/CD19 project/ASH abstract/forest/CR_mv_plot_IPTW.png"
)
knitr::include_graphics("/Users/aportugu/Desktop/CD19 project/ASH abstract/forest/CR_mv_plot_IPTW.png")
Show code
## Forest plot for MV PSM
df_fp <- mv_tab_PSM$table_body %>%
select(header_row, label, N_obs, N_event, estimate, conf.low, conf.high, p.value, ) %>%
mutate(
label = ifelse(header_row == TRUE | is.na(header_row),as.character(label), paste0(" ", as.character(label)) ),
p.value = signif(p.value, 2),
`OR (95% CI)` = ifelse(
is.na(estimate),"",paste0(round(estimate, 2), " (", round(conf.low,2), " to ",round(conf.high,2), ") ")
)
) %>%
rename(Characteristic = label,
N = N_obs,
Events = N_event,
`p value` = p.value)
forester(
left_side_data = df_fp[2],
right_side_data = df_fp[9:8],
estimate = df_fp$estimate,
ci_low = df_fp$conf.low,
ci_high = df_fp$conf.high,
estimate_col_name = "OR (95% CI)",
xlim = c(.05, 3),
null_line_at = 1,
arrows = TRUE,
x_scale_linear = FALSE,
arrow_labels = c("Worse", "Better"),
font_family = "sans",
display = TRUE,
nudge_x = .4,
nudge_height = .06,
stripe_colour = "#F5F5F5",
file_path = "/Users/aportugu/Desktop/CD19 project/ASH abstract/forest/CR_mv_plot_PSM.png"
)
knitr::include_graphics("/Users/aportugu/Desktop/CD19 project/ASH abstract/forest/CR_mv_plot_PSM.png")

Toxicity
Logistic Model - ICANS grade 1+
Show code
theme_gtsummary_compact()
preds <- c("ICANS.any","Product", "LDH pre-LD","ALC pre-LD", "Largest lesion", "Age", "Male sex", "CMV", "Bridging category")
data0 <- dataset %>%
mutate(
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
"Largest lesion" = Largest.lesion,
"HCT-CI" = HCT.CI,
"ALC pre-LD" = ALC.preLD,
"LDH pre-LD" = LDH.preLD/1000,
"Male sex" = ifelse(Sex == "M",1,0),
ICANS.any=ifelse(ICANS.grade == 0,0,1),
"Bridging category" = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD"), levels = c("No bridging","CR/PR","SD/PD"))
)
data1 <- IPTW.data %>%
mutate(
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
"Largest lesion" = Largest.lesion,
"HCT-CI" = HCT.CI,
"ALC pre-LD" = ALC.preLD,
"LDH pre-LD" = LDH.preLD/1000,
"Male sex" = ifelse(Sex == "M",1,0),
ICANS.any=ifelse(ICANS.grade == 0,0,1),
"Bridging category" = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD"), levels = c("No bridging","CR/PR","SD/PD"))
)
data2 <- m.data %>%
mutate(
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
"Largest lesion" = Largest.lesion,
"HCT-CI" = HCT.CI,
"ALC pre-LD" = ALC.preLD,
"LDH pre-LD" = LDH.preLD/1000,
"Male sex" = ifelse(Sex == "M",1,0),
ICANS.any=ifelse(ICANS.grade == 0,0,1),
"Bridging category" = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD"), levels = c("No bridging","CR/PR","SD/PD"))
)
uv_tab <- tbl_uvregression(
data0[c(preds)],
method = glm,
y = ICANS.any,
method.args = list(family = binomial),
exponentiate = TRUE
)
mv_tab<-glm( ICANS.any ~ Product + `Largest lesion` + `ALC pre-LD` + Age + `Male sex` + `LDH pre-LD` + `Bridging category`, data0, family = binomial ) %>%
tbl_regression(exponentiate=TRUE)
uv_tab_IPTW <- tbl_uvregression(
data1[c(preds)],
method = glm,
y = ICANS.any,
method.args = list(family = binomial, weights = data1$weights),
exponentiate = TRUE
)
mv_tab_IPTW<-glm( ICANS.any ~ Product + `Largest lesion` + `ALC pre-LD` + Age + `Male sex` + `LDH pre-LD` + `Bridging category`, data1, family = binomial, weights=weights ) %>%
tbl_regression(exponentiate=TRUE)
uv_tab_PSM <- tbl_uvregression(
data2[c(preds)],
method = glm,
y = ICANS.any,
method.args = list(family = binomial, weights = data2$weights),
exponentiate = TRUE
)
mv_tab_PSM<-glm( ICANS.any ~ Product + `Largest lesion` + `ALC pre-LD` + Age + `Male sex` + `LDH pre-LD` + `Bridging category`, data2, family = binomial, weights=weights ) %>%
tbl_regression(exponentiate=TRUE)
row1 <- tbl_merge(list(uv_tab, mv_tab), tab_spanner = c("**Univariate**", "**Multivariable**"))
row2 <- tbl_merge(list(uv_tab_IPTW, mv_tab_IPTW))
row3 <- tbl_merge(list(uv_tab_PSM, mv_tab_PSM))
tbl_stack(list(row1, row2, row3), group_header = c("UNWEIGHTED ANALYSIS", "IPTW ANALYSIS", "PSM ANALYSIS"), quiet=TRUE)
| Characteristic |
Univariate
|
Multivariable
|
| N |
OR |
95% CI |
p-value |
OR |
95% CI |
p-value |
| UNWEIGHTED ANALYSIS |
| Product |
149 |
|
|
|
|
|
|
| Liso-cel |
|
— |
— |
|
— |
— |
|
| Axi-cel |
|
2.84 |
1.39, 6.06 |
0.005 |
3.08 |
1.28, 7.84 |
0.014 |
| LDH pre-LD |
148 |
12.9 |
2.57, 124 |
0.009 |
8.15 |
1.63, 68.9 |
0.024 |
| ALC pre-LD |
149 |
1.29 |
0.96, 2.17 |
0.3 |
1.81 |
1.04, 3.36 |
0.043 |
| Largest lesion |
149 |
1.18 |
1.07, 1.32 |
0.002 |
1.18 |
1.05, 1.33 |
0.009 |
| Age |
149 |
1.01 |
0.98, 1.04 |
0.5 |
1.03 |
1.00, 1.06 |
0.072 |
| Male sex |
149 |
1.56 |
0.80, 3.10 |
0.2 |
1.57 |
0.72, 3.51 |
0.3 |
| CMV |
149 |
14.5 |
5.90, 41.4 |
<0.001 |
|
|
|
| Bridging category |
145 |
|
|
|
|
|
|
| No bridging |
|
— |
— |
|
— |
— |
|
| CR/PR |
|
0.63 |
0.22, 1.67 |
0.4 |
0.71 |
0.22, 2.17 |
0.6 |
| SD/PD |
|
1.57 |
0.72, 3.46 |
0.3 |
0.97 |
0.35, 2.62 |
>0.9 |
| IPTW ANALYSIS |
| Product |
126 |
|
|
|
|
|
|
| Liso-cel |
|
— |
— |
|
— |
— |
|
| Axi-cel |
|
1.75 |
0.82, 3.83 |
0.2 |
1.70 |
0.70, 4.28 |
0.2 |
| LDH pre-LD |
125 |
16.7 |
2.56, 239 |
0.014 |
11.2 |
1.73, 146 |
0.028 |
| ALC pre-LD |
126 |
1.41 |
0.96, 2.63 |
0.2 |
1.89 |
1.01, 3.88 |
0.059 |
| Largest lesion |
126 |
1.19 |
1.07, 1.35 |
0.002 |
1.20 |
1.06, 1.38 |
0.005 |
| Age |
126 |
1.01 |
0.98, 1.04 |
0.6 |
1.02 |
0.99, 1.06 |
0.3 |
| Male sex |
126 |
1.07 |
0.51, 2.25 |
0.9 |
1.15 |
0.49, 2.72 |
0.8 |
| CMV |
126 |
15.9 |
5.99, 51.0 |
<0.001 |
|
|
|
| Bridging category |
123 |
|
|
|
|
|
|
| No bridging |
|
— |
— |
|
— |
— |
|
| CR/PR |
|
0.60 |
0.20, 1.63 |
0.3 |
0.56 |
0.17, 1.72 |
0.3 |
| SD/PD |
|
1.47 |
0.63, 3.48 |
0.4 |
0.76 |
0.25, 2.23 |
0.6 |
| PSM ANALYSIS |
| Product |
149 |
|
|
|
|
|
|
| Liso-cel |
|
— |
— |
|
— |
— |
|
| Axi-cel |
|
1.64 |
0.80, 3.51 |
0.2 |
1.65 |
0.67, 4.31 |
0.3 |
| LDH pre-LD |
148 |
25.1 |
3.27, 368 |
0.007 |
9.80 |
1.12, 175 |
0.076 |
| ALC pre-LD |
149 |
1.29 |
0.97, 2.22 |
0.3 |
2.12 |
1.17, 4.13 |
0.017 |
| Largest lesion |
149 |
1.28 |
1.13, 1.47 |
<0.001 |
1.28 |
1.11, 1.50 |
0.002 |
| Age |
149 |
0.97 |
0.93, 1.00 |
0.061 |
0.97 |
0.93, 1.01 |
0.2 |
| Male sex |
149 |
1.36 |
0.68, 2.79 |
0.4 |
1.10 |
0.48, 2.54 |
0.8 |
| CMV |
149 |
26.0 |
9.63, 86.1 |
<0.001 |
|
|
|
| Bridging category |
144 |
|
|
|
|
|
|
| No bridging |
|
— |
— |
|
— |
— |
|
| CR/PR |
|
0.49 |
0.15, 1.34 |
0.2 |
0.43 |
0.10, 1.43 |
0.2 |
| SD/PD |
|
2.18 |
0.93, 5.19 |
0.073 |
0.78 |
0.23, 2.43 |
0.7 |
Logistic Model - ICANS grade 2+
Show code
theme_gtsummary_compact()
preds <- c("ICANS2.4","Product", "LDH pre-LD","ALC pre-LD", "Largest lesion", "Age", "Male sex", "Bridging category")
data0 <- dataset %>%
mutate(
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
"Largest lesion" = Largest.lesion,
"HCT-CI" = HCT.CI,
"ALC pre-LD" = ALC.preLD,
"LDH pre-LD" = LDH.preLD/1000,
"Male sex" = ifelse(Sex == "M",1,0),
ICANS2.4=ifelse(ICANS.grade == 0 | ICANS.grade == 1 ,0,1),
"Bridging category" = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD"), levels = c("No bridging","CR/PR","SD/PD"))
)
data1 <- IPTW.data %>%
mutate(
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
"Largest lesion" = Largest.lesion,
"HCT-CI" = HCT.CI,
"ALC pre-LD" = ALC.preLD,
"LDH pre-LD" = LDH.preLD/1000,
"Male sex" = ifelse(Sex == "M",1,0),
ICANS2.4=ifelse(ICANS.grade == 0 | ICANS.grade == 1 ,0,1),
"Bridging category" = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD"), levels = c("No bridging","CR/PR","SD/PD"))
)
data2 <- m.data %>%
mutate(
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
"Largest lesion" = Largest.lesion,
"HCT-CI" = HCT.CI,
"ALC pre-LD" = ALC.preLD,
"LDH pre-LD" = LDH.preLD/1000,
"Male sex" = ifelse(Sex == "M",1,0),
ICANS2.4=ifelse(ICANS.grade == 0 | ICANS.grade == 1 ,0,1),
"Bridging category" = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD"), levels = c("No bridging","CR/PR","SD/PD"))
)
uv_tab <- tbl_uvregression(
data0[c(preds)],
method = glm,
y = ICANS2.4,
method.args = list(family = binomial),
exponentiate = TRUE
)
mv_tab<-glm( ICANS2.4 ~ Product + `Largest lesion` + `ALC pre-LD` + Age + `Male sex` + `LDH pre-LD` + `Bridging category`, data0, family = binomial ) %>%
tbl_regression(exponentiate=TRUE)
uv_tab_IPTW <- tbl_uvregression(
data1[c(preds)],
method = glm,
y = ICANS2.4,
method.args = list(family = binomial, weights = data1$weights),
exponentiate = TRUE
)
mv_tab_IPTW<-glm( ICANS2.4 ~ Product + `Largest lesion` + `ALC pre-LD` + Age + `Male sex` + `LDH pre-LD`+ `Bridging category`, data1, family = binomial, weights=weights ) %>%
tbl_regression(exponentiate=TRUE)
uv_tab_PSM <- tbl_uvregression(
data2[c(preds)],
method = glm,
y = ICANS2.4,
method.args = list(family = binomial, weights = data2$weights),
exponentiate = TRUE
)
mv_tab_PSM<-glm( ICANS2.4 ~ Product + `Largest lesion` + `ALC pre-LD` + Age + `Male sex` + `LDH pre-LD`+ `Bridging category`, data2, family = binomial, weights=weights ) %>%
tbl_regression(exponentiate=TRUE)
row1 <- tbl_merge(list(uv_tab, mv_tab), tab_spanner = c("**Univariate**", "**Multivariable**"))
row2 <- tbl_merge(list(uv_tab_IPTW, mv_tab_IPTW))
row3 <- tbl_merge(list(uv_tab_PSM, mv_tab_PSM))
tbl_stack(list(row1, row2, row3), group_header = c("UNWEIGHTED ANALYSIS", "IPTW ANALYSIS", "PSM ANALYSIS"), quiet=TRUE)
| Characteristic |
Univariate
|
Multivariable
|
| N |
OR |
95% CI |
p-value |
OR |
95% CI |
p-value |
| UNWEIGHTED ANALYSIS |
| Product |
149 |
|
|
|
|
|
|
| Liso-cel |
|
— |
— |
|
— |
— |
|
| Axi-cel |
|
2.15 |
1.02, 4.75 |
0.050 |
1.88 |
0.78, 4.80 |
0.2 |
| LDH pre-LD |
148 |
6.62 |
1.82, 34.8 |
0.010 |
6.13 |
1.50, 35.0 |
0.021 |
| ALC pre-LD |
149 |
1.20 |
0.96, 1.92 |
0.3 |
1.49 |
0.95, 2.63 |
0.2 |
| Largest lesion |
149 |
1.15 |
1.04, 1.27 |
0.007 |
1.16 |
1.03, 1.31 |
0.019 |
| Age |
149 |
1.01 |
0.98, 1.04 |
0.5 |
1.03 |
0.99, 1.06 |
0.12 |
| Male sex |
149 |
1.81 |
0.89, 3.80 |
0.11 |
2.03 |
0.90, 4.78 |
0.095 |
| Bridging category |
145 |
|
|
|
|
|
|
| No bridging |
|
— |
— |
|
— |
— |
|
| CR/PR |
|
0.55 |
0.17, 1.55 |
0.3 |
0.60 |
0.16, 1.90 |
0.4 |
| SD/PD |
|
1.25 |
0.56, 2.75 |
0.6 |
0.63 |
0.21, 1.70 |
0.4 |
| IPTW ANALYSIS |
| Product |
126 |
|
|
|
|
|
|
| Liso-cel |
|
— |
— |
|
— |
— |
|
| Axi-cel |
|
1.29 |
0.59, 2.91 |
0.5 |
1.09 |
0.44, 2.75 |
0.9 |
| LDH pre-LD |
125 |
8.14 |
1.81, 59.0 |
0.015 |
7.60 |
1.52, 58.2 |
0.026 |
| ALC pre-LD |
126 |
1.22 |
0.93, 2.15 |
0.4 |
1.55 |
0.91, 3.01 |
0.2 |
| Largest lesion |
126 |
1.17 |
1.05, 1.31 |
0.005 |
1.19 |
1.05, 1.36 |
0.009 |
| Age |
126 |
1.01 |
0.98, 1.04 |
0.7 |
1.01 |
0.98, 1.05 |
0.4 |
| Male sex |
126 |
1.31 |
0.61, 2.89 |
0.5 |
1.53 |
0.64, 3.83 |
0.3 |
| Bridging category |
123 |
|
|
|
|
|
|
| No bridging |
|
— |
— |
|
— |
— |
|
| CR/PR |
|
0.57 |
0.17, 1.65 |
0.3 |
0.54 |
0.14, 1.71 |
0.3 |
| SD/PD |
|
1.25 |
0.52, 2.94 |
0.6 |
0.53 |
0.16, 1.57 |
0.3 |
| PSM ANALYSIS |
| Product |
149 |
|
|
|
|
|
|
| Liso-cel |
|
— |
— |
|
— |
— |
|
| Axi-cel |
|
1.67 |
0.79, 3.71 |
0.2 |
1.64 |
0.65, 4.46 |
0.3 |
| LDH pre-LD |
148 |
13.5 |
2.26, 137 |
0.012 |
6.27 |
0.89, 82.3 |
0.11 |
| ALC pre-LD |
149 |
1.24 |
0.97, 2.07 |
0.3 |
1.98 |
1.08, 3.75 |
0.028 |
| Largest lesion |
149 |
1.25 |
1.11, 1.43 |
<0.001 |
1.25 |
1.09, 1.46 |
0.003 |
| Age |
149 |
0.96 |
0.92, 1.00 |
0.032 |
0.96 |
0.92, 1.00 |
0.069 |
| Male sex |
149 |
1.47 |
0.71, 3.11 |
0.3 |
1.24 |
0.53, 2.96 |
0.6 |
| Bridging category |
144 |
|
|
|
|
|
|
| No bridging |
|
— |
— |
|
— |
— |
|
| CR/PR |
|
0.39 |
0.10, 1.17 |
0.12 |
0.33 |
0.07, 1.21 |
0.13 |
| SD/PD |
|
1.95 |
0.82, 4.62 |
0.13 |
0.64 |
0.19, 1.99 |
0.5 |
Logistic Model - ICANS grade 3+
Show code
theme_gtsummary_compact()
preds <- c("ICANS3.4","Product", "LDH pre-LD","ALC pre-LD", "Largest lesion", "Age", "Male sex", "CMV", "Bridging category")
data0 <- dataset %>%
mutate(
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
"Largest lesion" = Largest.lesion,
"HCT-CI" = HCT.CI,
"ALC pre-LD" = ALC.preLD,
"LDH pre-LD" = LDH.preLD/1000,
"Male sex" = ifelse(Sex == "M",1,0),
ICANS3.4=ifelse(ICANS.grade == 3 | ICANS.grade == 4,1,0),
"Bridging category" = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD"), levels = c("No bridging","CR/PR","SD/PD"))
)
data1 <- IPTW.data %>%
mutate(
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
"Largest lesion" = Largest.lesion,
"HCT-CI" = HCT.CI,
"ALC pre-LD" = ALC.preLD,
"LDH pre-LD" = LDH.preLD/1000,
"Male sex" = ifelse(Sex == "M",1,0),
ICANS3.4=ifelse(ICANS.grade == 3 | ICANS.grade == 4,1,0),
"Bridging category" = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD"), levels = c("No bridging","CR/PR","SD/PD"))
)
data2 <- m.data %>%
mutate(
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
"Largest lesion" = Largest.lesion,
"HCT-CI" = HCT.CI,
"ALC pre-LD" = ALC.preLD,
"LDH pre-LD" = LDH.preLD/1000,
"Male sex" = ifelse(Sex == "M",1,0),
ICANS3.4=ifelse(ICANS.grade == 3 | ICANS.grade == 4,1,0),
"Bridging category" = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD"), levels = c("No bridging","CR/PR","SD/PD"))
)
uv_tab <- tbl_uvregression(
data0[c(preds)],
method = glm,
y = ICANS3.4,
method.args = list(family = binomial),
exponentiate = TRUE
)
mv_tab<-glm( ICANS3.4 ~ Product + `Largest lesion` + `ALC pre-LD` + Age + `Male sex` + `LDH pre-LD` + `Bridging category`, data0, family = binomial ) %>% tbl_regression(exponentiate=TRUE)
uv_tab_IPTW <- tbl_uvregression(
data1[c(preds)],
method = glm,
y = ICANS3.4,
method.args = list(family = binomial, weights = data1$weights),
exponentiate = TRUE
)
mv_tab_IPTW<-glm( ICANS3.4 ~ Product + `Largest lesion` + `ALC pre-LD` + Age + `Male sex` + `LDH pre-LD` + `Bridging category`, data1, family = binomial, weights=weights ) %>%
tbl_regression(exponentiate=TRUE)
uv_tab_PSM <- tbl_uvregression(
data2[c(preds)],
method = glm,
y = ICANS3.4,
method.args = list(family = binomial, weights = data2$weights),
exponentiate = TRUE
)
mv_tab_PSM<-glm( ICANS3.4 ~ Product + `Largest lesion` + `ALC pre-LD` + Age + `Male sex` + `LDH pre-LD` + `Bridging category`, data2, family = binomial, weights=weights ) %>%
tbl_regression(exponentiate=TRUE)
row1 <- tbl_merge(list(uv_tab, mv_tab), tab_spanner = c("**Univariate**", "**Multivariable**"))
row2 <- tbl_merge(list(uv_tab_IPTW, mv_tab_IPTW))
row3 <- tbl_merge(list(uv_tab_PSM, mv_tab_PSM))
tbl_stack(list(row1, row2, row3), group_header = c("UNWEIGHTED ANALYSIS", "IPTW ANALYSIS", "PSM ANALYSIS"), quiet=TRUE)
| Characteristic |
Univariate
|
Multivariable
|
| N |
OR |
95% CI |
p-value |
OR |
95% CI |
p-value |
| UNWEIGHTED ANALYSIS |
| Product |
149 |
|
|
|
|
|
|
| Liso-cel |
|
— |
— |
|
— |
— |
|
| Axi-cel |
|
1.01 |
0.43, 2.54 |
>0.9 |
0.85 |
0.30, 2.45 |
0.8 |
| LDH pre-LD |
148 |
2.59 |
1.09, 8.63 |
0.12 |
2.58 |
1.08, 10.6 |
0.2 |
| ALC pre-LD |
149 |
0.97 |
0.59, 1.19 |
0.8 |
0.94 |
0.63, 1.15 |
0.6 |
| Largest lesion |
149 |
1.15 |
1.03, 1.29 |
0.012 |
1.15 |
1.01, 1.31 |
0.039 |
| Age |
149 |
1.02 |
0.98, 1.05 |
0.3 |
1.03 |
0.99, 1.08 |
0.2 |
| Male sex |
149 |
1.92 |
0.78, 5.20 |
0.2 |
2.82 |
1.01, 9.18 |
0.061 |
| CMV |
149 |
17.8 |
6.75, 54.0 |
<0.001 |
|
|
|
| Bridging category |
145 |
|
|
|
|
|
|
| No bridging |
|
— |
— |
|
— |
— |
|
| CR/PR |
|
1.36 |
0.35, 4.41 |
0.6 |
1.56 |
0.37, 5.69 |
0.5 |
| SD/PD |
|
2.22 |
0.85, 5.67 |
0.10 |
1.33 |
0.40, 4.12 |
0.6 |
| IPTW ANALYSIS |
| Product |
126 |
|
|
|
|
|
|
| Liso-cel |
|
— |
— |
|
— |
— |
|
| Axi-cel |
|
0.60 |
0.24, 1.53 |
0.3 |
0.48 |
0.17, 1.37 |
0.2 |
| LDH pre-LD |
125 |
3.34 |
1.06, 13.6 |
0.075 |
3.65 |
1.09, 18.2 |
0.094 |
| ALC pre-LD |
126 |
0.97 |
0.55, 1.22 |
0.8 |
0.92 |
0.59, 1.16 |
0.5 |
| Largest lesion |
126 |
1.17 |
1.04, 1.32 |
0.008 |
1.15 |
1.01, 1.33 |
0.037 |
| Age |
126 |
1.00 |
0.97, 1.04 |
0.8 |
1.02 |
0.97, 1.06 |
0.5 |
| Male sex |
126 |
1.41 |
0.55, 3.91 |
0.5 |
2.08 |
0.71, 6.99 |
0.2 |
| CMV |
126 |
17.3 |
6.21, 56.2 |
<0.001 |
|
|
|
| Bridging category |
123 |
|
|
|
|
|
|
| No bridging |
|
— |
— |
|
— |
— |
|
| CR/PR |
|
1.28 |
0.33, 4.24 |
0.7 |
1.24 |
0.29, 4.50 |
0.8 |
| SD/PD |
|
2.01 |
0.72, 5.47 |
0.2 |
0.94 |
0.24, 3.20 |
>0.9 |
| PSM ANALYSIS |
| Product |
149 |
|
|
|
|
|
|
| Liso-cel |
|
— |
— |
|
— |
— |
|
| Axi-cel |
|
0.95 |
0.40, 2.41 |
>0.9 |
0.83 |
0.30, 2.38 |
0.7 |
| LDH pre-LD |
148 |
5.02 |
1.04, 28.6 |
0.051 |
2.95 |
0.62, 22.9 |
0.3 |
| ALC pre-LD |
149 |
0.99 |
0.65, 1.21 |
>0.9 |
0.94 |
0.68, 1.16 |
0.6 |
| Largest lesion |
149 |
1.21 |
1.07, 1.38 |
0.003 |
1.17 |
1.02, 1.35 |
0.028 |
| Age |
149 |
0.97 |
0.93, 1.01 |
0.13 |
0.98 |
0.93, 1.03 |
0.4 |
| Male sex |
149 |
1.70 |
0.70, 4.55 |
0.3 |
1.54 |
0.57, 4.50 |
0.4 |
| CMV |
149 |
12.6 |
4.95, 34.4 |
<0.001 |
|
|
|
| Bridging category |
144 |
|
|
|
|
|
|
| No bridging |
|
— |
— |
|
— |
— |
|
| CR/PR |
|
0.89 |
0.21, 2.97 |
0.9 |
0.81 |
0.18, 2.92 |
0.8 |
| SD/PD |
|
2.50 |
0.92, 6.60 |
0.067 |
1.03 |
0.28, 3.44 |
>0.9 |
Logistic Model - CRS grade 1+
Show code
theme_gtsummary_compact()
preds <- c("CRS.any","Product", "LDH pre-LD","ALC pre-LD", "Largest lesion", "Age", "Male sex", "CMV", "Bridging category")
data0 <- dataset %>%
mutate(
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
"Largest lesion" = Largest.lesion,
"HCT-CI" = HCT.CI,
"ALC pre-LD" = ALC.preLD,
"LDH pre-LD" = LDH.preLD/1000,
"Male sex" = ifelse(Sex == "M",1,0),
CRS.any=ifelse(CRS.grade == 0,0,1),
"Bridging category" = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD"), levels = c("No bridging","CR/PR","SD/PD"))
)
data1 <- IPTW.data %>%
mutate(
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
"Largest lesion" = Largest.lesion,
"HCT-CI" = HCT.CI,
"ALC pre-LD" = ALC.preLD,
"LDH pre-LD" = LDH.preLD/1000,
"Male sex" = ifelse(Sex == "M",1,0),
CRS.any=ifelse(CRS.grade == 0,0,1),
"Bridging category" = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD"), levels = c("No bridging","CR/PR","SD/PD"))
)
data2 <- m.data %>%
mutate(
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
"Largest lesion" = Largest.lesion,
"HCT-CI" = HCT.CI,
"ALC pre-LD" = ALC.preLD,
"LDH pre-LD" = LDH.preLD/1000,
"Male sex" = ifelse(Sex == "M",1,0),
CRS.any=ifelse(CRS.grade == 0,0,1),
"Bridging category" = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD"), levels = c("No bridging","CR/PR","SD/PD"))
)
uv_tab <- tbl_uvregression(
data0[c(preds)],
method = glm,
y = CRS.any,
method.args = list(family = binomial),
exponentiate = TRUE
)
mv_tab<-glm( CRS.any ~ Product + `Largest lesion` + `ALC pre-LD` + Age + `Male sex` + `LDH pre-LD` + `Bridging category`, data0, family = binomial ) %>% tbl_regression(exponentiate=TRUE)
uv_tab_IPTW <- tbl_uvregression(
data1[c(preds)],
method = glm,
y = CRS.any,
method.args = list(family = binomial, weights = data1$weights),
exponentiate = TRUE
)
mv_tab_IPTW<-glm( CRS.any ~ Product + `Largest lesion` + `ALC pre-LD` + Age + `Male sex` + `LDH pre-LD` + `Bridging category`, data1, family = binomial, weights=weights ) %>%
tbl_regression(exponentiate=TRUE)
uv_tab_PSM <- tbl_uvregression(
data2[c(preds)],
method = glm,
y = CRS.any,
method.args = list(family = binomial, weights = data2$weights),
exponentiate = TRUE
)
mv_tab_PSM<-glm( CRS.any ~ Product + `Largest lesion` + `ALC pre-LD` + Age + `Male sex` + `LDH pre-LD` + `Bridging category`, data2, family = binomial, weights=weights ) %>%
tbl_regression(exponentiate=TRUE)
row1 <- tbl_merge(list(uv_tab, mv_tab), tab_spanner = c("**Univariate**", "**Multivariable**"))
row2 <- tbl_merge(list(uv_tab_IPTW, mv_tab_IPTW))
row3 <- tbl_merge(list(uv_tab_PSM, mv_tab_PSM))
tbl_stack(list(row1, row2, row3), group_header = c("UNWEIGHTED ANALYSIS", "IPTW ANALYSIS", "PSM ANALYSIS"), quiet=TRUE)
| Characteristic |
Univariate
|
Multivariable
|
| N |
OR |
95% CI |
p-value |
OR |
95% CI |
p-value |
| UNWEIGHTED ANALYSIS |
| Product |
149 |
|
|
|
|
|
|
| Liso-cel |
|
— |
— |
|
— |
— |
|
| Axi-cel |
|
4.50 |
1.95, 10.8 |
<0.001 |
4.71 |
1.60, 14.9 |
0.006 |
| LDH pre-LD |
148 |
89.4 |
2.31, 25,644 |
0.065 |
89.0 |
1.37, 47,171 |
0.10 |
| ALC pre-LD |
149 |
1.69 |
0.94, 4.14 |
0.2 |
3.35 |
1.37, 11.8 |
0.028 |
| Largest lesion |
149 |
1.28 |
1.09, 1.56 |
0.006 |
1.30 |
1.09, 1.61 |
0.007 |
| Age |
149 |
0.98 |
0.94, 1.01 |
0.2 |
0.99 |
0.94, 1.03 |
0.5 |
| Male sex |
149 |
0.85 |
0.35, 1.95 |
0.7 |
0.52 |
0.17, 1.46 |
0.2 |
| CMV |
149 |
14.0 |
2.82, 254 |
0.011 |
|
|
|
| Bridging category |
145 |
|
|
|
|
|
|
| No bridging |
|
— |
— |
|
— |
— |
|
| CR/PR |
|
0.28 |
0.10, 0.83 |
0.019 |
0.23 |
0.06, 0.85 |
0.027 |
| SD/PD |
|
0.72 |
0.27, 2.07 |
0.5 |
0.30 |
0.08, 1.08 |
0.065 |
| IPTW ANALYSIS |
| Product |
126 |
|
|
|
|
|
|
| Liso-cel |
|
— |
— |
|
— |
— |
|
| Axi-cel |
|
2.69 |
1.12, 6.54 |
0.027 |
3.89 |
1.26, 13.1 |
0.021 |
| LDH pre-LD |
125 |
667 |
5.16, 671,492 |
0.033 |
433 |
2.95, 533,357 |
0.051 |
| ALC pre-LD |
126 |
2.05 |
0.96, 5.88 |
0.13 |
3.30 |
1.20, 14.0 |
0.057 |
| Largest lesion |
126 |
1.26 |
1.07, 1.53 |
0.012 |
1.30 |
1.09, 1.62 |
0.007 |
| Age |
126 |
0.97 |
0.93, 1.01 |
0.2 |
0.98 |
0.93, 1.02 |
0.3 |
| Male sex |
126 |
0.53 |
0.18, 1.34 |
0.2 |
0.33 |
0.08, 1.07 |
0.080 |
| CMV |
126 |
22.5 |
3.52, 1,160 |
0.014 |
|
|
|
| Bridging category |
123 |
|
|
|
|
|
|
| No bridging |
|
— |
— |
|
— |
— |
|
| CR/PR |
|
0.22 |
0.07, 0.67 |
0.007 |
0.16 |
0.04, 0.63 |
0.010 |
| SD/PD |
|
0.68 |
0.23, 2.14 |
0.5 |
0.24 |
0.06, 1.00 |
0.052 |
| PSM ANALYSIS |
| Product |
149 |
|
|
|
|
|
|
| Liso-cel |
|
— |
— |
|
— |
— |
|
| Axi-cel |
|
2.11 |
0.99, 4.49 |
0.053 |
3.53 |
1.27, 10.5 |
0.018 |
| LDH pre-LD |
148 |
126 |
3.12, 21,564 |
0.034 |
522 |
5.46, 178,178 |
0.018 |
| ALC pre-LD |
149 |
3.62 |
1.54, 9.78 |
0.006 |
4.78 |
1.78, 18.6 |
0.010 |
| Largest lesion |
149 |
1.21 |
1.05, 1.45 |
0.018 |
1.29 |
1.08, 1.59 |
0.009 |
| Age |
149 |
1.00 |
0.96, 1.04 |
>0.9 |
0.99 |
0.94, 1.04 |
0.7 |
| Male sex |
149 |
0.34 |
0.14, 0.77 |
0.013 |
0.22 |
0.07, 0.65 |
0.009 |
| CMV |
149 |
16.7 |
3.40, 303 |
0.006 |
|
|
|
| Bridging category |
144 |
|
|
|
|
|
|
| No bridging |
|
— |
— |
|
— |
— |
|
| CR/PR |
|
0.17 |
0.06, 0.44 |
<0.001 |
0.16 |
0.04, 0.52 |
0.003 |
| SD/PD |
|
0.81 |
0.30, 2.39 |
0.7 |
0.51 |
0.13, 1.98 |
0.3 |
Logistic Model - CRS grade 2+
Show code
theme_gtsummary_compact()
preds <- c("CRS2.4","Product", "LDH pre-LD","ALC pre-LD", "Largest lesion", "Age", "Male sex", "CMV", "Bridging category")
data0 <- dataset %>%
mutate(
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
"Largest lesion" = Largest.lesion,
"HCT-CI" = HCT.CI,
"ALC pre-LD" = ALC.preLD,
"LDH pre-LD" = LDH.preLD/1000,
"Male sex" = ifelse(Sex == "M",1,0),
CRS2.4=ifelse(CRS.grade == 0 | CRS.grade == 1 ,0,1),
"Bridging category" = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD"), levels = c("No bridging","CR/PR","SD/PD"))
)
data1 <- IPTW.data %>%
mutate(
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
"Largest lesion" = Largest.lesion,
"HCT-CI" = HCT.CI,
"ALC pre-LD" = ALC.preLD,
"LDH pre-LD" = LDH.preLD/1000,
"Male sex" = ifelse(Sex == "M",1,0),
CRS2.4=ifelse(CRS.grade == 0 | CRS.grade == 1 ,0,1),
"Bridging category" = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD"), levels = c("No bridging","CR/PR","SD/PD"))
)
data2 <- m.data %>%
mutate(
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
"Largest lesion" = Largest.lesion,
"HCT-CI" = HCT.CI,
"ALC pre-LD" = ALC.preLD,
"LDH pre-LD" = LDH.preLD/1000,
"Male sex" = ifelse(Sex == "M",1,0),
CRS2.4=ifelse(CRS.grade == 0 | CRS.grade == 1 ,0,1),
"Bridging category" = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD"), levels = c("No bridging","CR/PR","SD/PD"))
)
uv_tab <- tbl_uvregression(
data0[c(preds)],
method = glm,
y = CRS2.4,
method.args = list(family = binomial),
exponentiate = TRUE
)
mv_tab<-glm( CRS2.4 ~ Product + `Largest lesion` + `ALC pre-LD` + Age + `Male sex` + `LDH pre-LD` + `Bridging category`, data0, family = binomial ) %>% tbl_regression(exponentiate=TRUE)
uv_tab_IPTW <- tbl_uvregression(
data1[c(preds)],
method = glm,
y = CRS2.4,
method.args = list(family = binomial, weights = data1$weights),
exponentiate = TRUE
)
mv_tab_IPTW<-glm( CRS2.4 ~ Product + `Largest lesion` + `ALC pre-LD` + Age + `Male sex` + `LDH pre-LD` + `Bridging category`, data1, family = binomial, weights=weights ) %>%
tbl_regression(exponentiate=TRUE)
uv_tab_PSM <- tbl_uvregression(
data2[c(preds)],
method = glm,
y = CRS2.4,
method.args = list(family = binomial, weights = data2$weights),
exponentiate = TRUE
)
mv_tab_PSM<-glm( CRS2.4 ~ Product + `Largest lesion` + `ALC pre-LD` + Age + `Male sex` + `LDH pre-LD` + `Bridging category`, data2, family = binomial, weights=weights ) %>%
tbl_regression(exponentiate=TRUE)
row1 <- tbl_merge(list(uv_tab, mv_tab), tab_spanner = c("**Univariate**", "**Multivariable**"))
row2 <- tbl_merge(list(uv_tab_IPTW, mv_tab_IPTW))
row3 <- tbl_merge(list(uv_tab_PSM, mv_tab_PSM))
tbl_stack(list(row1, row2, row3), group_header = c("UNWEIGHTED ANALYSIS", "IPTW ANALYSIS", "PSM ANALYSIS"), quiet=TRUE)
| Characteristic |
Univariate
|
Multivariable
|
| N |
OR |
95% CI |
p-value |
OR |
95% CI |
p-value |
| UNWEIGHTED ANALYSIS |
| Product |
149 |
|
|
|
|
|
|
| Liso-cel |
|
— |
— |
|
— |
— |
|
| Axi-cel |
|
4.08 |
1.90, 9.46 |
<0.001 |
4.25 |
1.79, 11.0 |
0.002 |
| LDH pre-LD |
148 |
0.96 |
0.59, 1.29 |
0.8 |
0.88 |
0.47, 1.20 |
0.5 |
| ALC pre-LD |
149 |
0.94 |
0.66, 1.14 |
0.6 |
0.98 |
0.72, 1.19 |
0.9 |
| Largest lesion |
149 |
1.08 |
0.98, 1.19 |
0.11 |
1.08 |
0.97, 1.20 |
0.2 |
| Age |
149 |
0.99 |
0.96, 1.01 |
0.3 |
1.00 |
0.97, 1.03 |
>0.9 |
| Male sex |
149 |
0.84 |
0.43, 1.66 |
0.6 |
0.69 |
0.32, 1.45 |
0.3 |
| CMV |
149 |
2.13 |
1.03, 4.46 |
0.042 |
|
|
|
| Bridging category |
145 |
|
|
|
|
|
|
| No bridging |
|
— |
— |
|
— |
— |
|
| CR/PR |
|
1.14 |
0.42, 2.97 |
0.8 |
1.68 |
0.57, 4.98 |
0.3 |
| SD/PD |
|
1.21 |
0.55, 2.65 |
0.6 |
1.18 |
0.47, 2.96 |
0.7 |
| IPTW ANALYSIS |
| Product |
126 |
|
|
|
|
|
|
| Liso-cel |
|
— |
— |
|
— |
— |
|
| Axi-cel |
|
3.07 |
1.36, 7.45 |
0.009 |
3.19 |
1.32, 8.36 |
0.013 |
| LDH pre-LD |
125 |
1.00 |
0.58, 1.53 |
>0.9 |
0.91 |
0.47, 1.38 |
0.6 |
| ALC pre-LD |
126 |
0.97 |
0.67, 1.21 |
0.8 |
0.98 |
0.69, 1.24 |
0.9 |
| Largest lesion |
126 |
1.06 |
0.96, 1.17 |
0.3 |
1.07 |
0.95, 1.20 |
0.2 |
| Age |
126 |
0.99 |
0.96, 1.02 |
0.5 |
1.00 |
0.96, 1.03 |
0.8 |
| Male sex |
126 |
0.58 |
0.27, 1.21 |
0.15 |
0.49 |
0.21, 1.09 |
0.083 |
| CMV |
126 |
2.36 |
1.08, 5.22 |
0.032 |
|
|
|
| Bridging category |
123 |
|
|
|
|
|
|
| No bridging |
|
— |
— |
|
— |
— |
|
| CR/PR |
|
0.99 |
0.35, 2.69 |
>0.9 |
1.09 |
0.37, 3.17 |
0.9 |
| SD/PD |
|
1.16 |
0.49, 2.73 |
0.7 |
1.04 |
0.38, 2.84 |
>0.9 |
| PSM ANALYSIS |
| Product |
149 |
|
|
|
|
|
|
| Liso-cel |
|
— |
— |
|
— |
— |
|
| Axi-cel |
|
3.86 |
1.79, 8.95 |
<0.001 |
5.14 |
2.05, 14.3 |
<0.001 |
| LDH pre-LD |
148 |
1.20 |
0.40, 5.14 |
0.7 |
0.98 |
0.27, 6.34 |
>0.9 |
| ALC pre-LD |
149 |
1.00 |
0.78, 1.21 |
>0.9 |
0.97 |
0.73, 1.19 |
0.8 |
| Largest lesion |
149 |
1.00 |
0.90, 1.11 |
>0.9 |
1.02 |
0.89, 1.17 |
0.7 |
| Age |
149 |
1.00 |
0.96, 1.03 |
>0.9 |
0.99 |
0.94, 1.03 |
0.6 |
| Male sex |
149 |
0.27 |
0.13, 0.54 |
<0.001 |
0.17 |
0.07, 0.39 |
<0.001 |
| CMV |
149 |
2.11 |
0.98, 4.59 |
0.058 |
|
|
|
| Bridging category |
144 |
|
|
|
|
|
|
| No bridging |
|
— |
— |
|
— |
— |
|
| CR/PR |
|
0.25 |
0.07, 0.72 |
0.017 |
0.39 |
0.11, 1.22 |
0.13 |
| SD/PD |
|
0.90 |
0.38, 2.09 |
0.8 |
1.38 |
0.45, 4.23 |
0.6 |
Logistic Model - CRS grade 3+
Show code
theme_gtsummary_compact()
preds <- c("CRS3.4","Product", "LDH pre-LD","ALC pre-LD", "Largest lesion", "Age", "Male sex", "CMV", "Bridging category")
data0 <- dataset %>%
mutate(
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
"Largest lesion" = Largest.lesion,
"HCT-CI" = HCT.CI,
"ALC pre-LD" = ALC.preLD,
"LDH pre-LD" = LDH.preLD/1000,
"Male sex" = ifelse(Sex == "M",1,0),
CRS3.4=ifelse(CRS.grade == 3 | CRS.grade == 4,1,0),
"Bridging category" = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD"), levels = c("No bridging","CR/PR","SD/PD"))
)
data1 <- IPTW.data %>%
mutate(
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
"Largest lesion" = Largest.lesion,
"HCT-CI" = HCT.CI,
"ALC pre-LD" = ALC.preLD,
"LDH pre-LD" = LDH.preLD/1000,
"Male sex" = ifelse(Sex == "M",1,0),
CRS3.4=ifelse(CRS.grade == 3 | CRS.grade == 4,1,0),
"Bridging category" = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD"), levels = c("No bridging","CR/PR","SD/PD"))
)
data2 <- m.data %>%
mutate(
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
"Largest lesion" = Largest.lesion,
"HCT-CI" = HCT.CI,
"ALC pre-LD" = ALC.preLD,
"LDH pre-LD" = LDH.preLD/1000,
"Male sex" = ifelse(Sex == "M",1,0),
CRS3.4=ifelse(CRS.grade == 3 | CRS.grade == 4,1,0),
"Bridging category" = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD"), levels = c("No bridging","CR/PR","SD/PD"))
)
uv_tab <- tbl_uvregression(
data0[c(preds)],
method = glm,
y = CRS3.4,
method.args = list(family = binomial),
exponentiate = TRUE
)
mv_tab<-glm( CRS3.4 ~ Product + `Largest lesion` + `ALC pre-LD` + Age + `Male sex` + `LDH pre-LD` + `Bridging category`, data0, family = binomial ) %>% tbl_regression(exponentiate=TRUE)
uv_tab_IPTW <- tbl_uvregression(
data1[c(preds)],
method = glm,
y = CRS3.4,
method.args = list(family = binomial, weights = data1$weights),
exponentiate = TRUE
)
mv_tab_IPTW<-glm( CRS3.4 ~ Product + `Largest lesion` + `ALC pre-LD` + Age + `Male sex` + `LDH pre-LD` + `Bridging category`, data1, family = binomial, weights=weights ) %>%
tbl_regression(exponentiate=TRUE)
uv_tab_PSM <- tbl_uvregression(
data2[c(preds)],
method = glm,
y = CRS3.4,
method.args = list(family = binomial, weights = data2$weights),
exponentiate = TRUE
)
mv_tab_PSM<-glm( CRS3.4 ~ Product + `Largest lesion` + `ALC pre-LD` + Age + `Male sex` + `LDH pre-LD` + `Bridging category`, data2, family = binomial, weights=weights ) %>%
tbl_regression(exponentiate=TRUE)
row1 <- tbl_merge(list(uv_tab, mv_tab), tab_spanner = c("**Univariate**", "**Multivariable**"))
row2 <- tbl_merge(list(uv_tab_IPTW, mv_tab_IPTW))
row3 <- tbl_merge(list(uv_tab_PSM, mv_tab_PSM))
tbl_stack(list(row1, row2, row3), group_header = c("UNWEIGHTED ANALYSIS", "IPTW ANALYSIS", "PSM ANALYSIS"), quiet=TRUE)
| Characteristic |
Univariate
|
Multivariable
|
| N |
OR |
95% CI |
p-value |
OR |
95% CI |
p-value |
| UNWEIGHTED ANALYSIS |
| Product |
149 |
|
|
|
|
|
|
| Liso-cel |
|
— |
— |
|
— |
— |
|
| Axi-cel |
|
4.31 |
0.76, 81.1 |
0.2 |
2.87 |
0.45, 56.2 |
0.3 |
| LDH pre-LD |
148 |
1.10 |
0.53, 1.50 |
0.6 |
1.10 |
0.52, 1.57 |
0.6 |
| ALC pre-LD |
149 |
0.66 |
0.13, 1.20 |
0.5 |
0.62 |
0.11, 1.31 |
0.5 |
| Largest lesion |
149 |
1.02 |
0.83, 1.21 |
0.8 |
0.99 |
0.78, 1.22 |
>0.9 |
| Age |
149 |
0.98 |
0.94, 1.04 |
0.5 |
1.00 |
0.95, 1.06 |
>0.9 |
| Male sex |
149 |
2.20 |
0.51, 15.1 |
0.3 |
2.09 |
0.45, 16.5 |
0.4 |
| CMV |
149 |
2.23 |
0.53, 8.86 |
0.3 |
|
|
|
| Bridging category |
145 |
|
|
|
|
|
|
| No bridging |
|
— |
— |
|
— |
— |
|
| CR/PR |
|
0.00 |
|
>0.9 |
0.00 |
|
>0.9 |
| SD/PD |
|
0.68 |
0.10, 2.99 |
0.6 |
0.68 |
0.08, 3.61 |
0.7 |
| IPTW ANALYSIS |
| Product |
126 |
|
|
|
|
|
|
| Liso-cel |
|
— |
— |
|
— |
— |
|
| Axi-cel |
|
2.70 |
0.50, 35.6 |
0.3 |
2.07 |
0.36, 28.1 |
0.5 |
| LDH pre-LD |
125 |
1.10 |
|
0.7 |
1.15 |
0.42, 1.80 |
0.6 |
| ALC pre-LD |
126 |
0.86 |
0.18, 1.30 |
0.8 |
0.71 |
0.12, 1.39 |
0.7 |
| Largest lesion |
126 |
0.98 |
0.77, 1.18 |
0.9 |
0.97 |
0.73, 1.22 |
0.8 |
| Age |
126 |
0.99 |
0.94, 1.06 |
0.8 |
1.00 |
0.94, 1.07 |
>0.9 |
| Male sex |
126 |
2.38 |
0.47, 23.8 |
0.4 |
2.31 |
0.42, 27.0 |
0.4 |
| CMV |
126 |
1.99 |
0.42, 8.67 |
0.4 |
|
|
|
| Bridging category |
123 |
|
|
|
|
|
|
| No bridging |
|
— |
— |
|
— |
— |
|
| CR/PR |
|
0.00 |
|
>0.9 |
0.00 |
|
>0.9 |
| SD/PD |
|
0.50 |
0.05, 2.57 |
0.5 |
0.55 |
0.04, 3.55 |
0.6 |
| PSM ANALYSIS |
| Product |
149 |
|
|
|
|
|
|
| Liso-cel |
|
— |
— |
|
— |
— |
|
| Axi-cel |
|
2.21 |
0.32, 43.6 |
0.5 |
1.72 |
0.22, 37.4 |
0.6 |
| LDH pre-LD |
148 |
1.17 |
|
0.8 |
1.28 |
|
0.6 |
| ALC pre-LD |
149 |
1.02 |
|
>0.9 |
1.10 |
|
0.7 |
| Largest lesion |
149 |
0.91 |
0.60, 1.19 |
0.6 |
0.89 |
0.53, 1.26 |
0.6 |
| Age |
149 |
0.99 |
0.91, 1.10 |
0.9 |
0.98 |
0.90, 1.10 |
0.8 |
| Male sex |
149 |
0.95 |
0.16, 7.09 |
>0.9 |
1.24 |
0.19, 10.6 |
0.8 |
| CMV |
149 |
1.76 |
0.21, 10.5 |
0.5 |
|
|
|
| Bridging category |
144 |
|
|
|
|
|
|
| No bridging |
|
— |
— |
|
— |
— |
|
| CR/PR |
|
0.00 |
|
>0.9 |
0.00 |
|
>0.9 |
| SD/PD |
|
0.27 |
0.00, 2.87 |
0.4 |
0.27 |
0.00, 4.48 |
0.5 |
Medication administration
Tocilizumab
Show code
theme_gtsummary_compact()
preds <- c("toci.doses","Product", "LDH pre-LD","ALC pre-LD", "Largest lesion", "Age", "Male sex", "CMV", "Bridging category")
data0 <- dataset %>%
mutate(
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
"Largest lesion" = Largest.lesion,
"HCT-CI" = HCT.CI,
"ALC pre-LD" = ALC.preLD,
"LDH pre-LD" = LDH.preLD/1000,
"Male sex" = ifelse(Sex == "M",1,0),
CRS2.4=ifelse(CRS.grade == 0 | CRS.grade == 1 ,0,1),
"Bridging category" = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD"), levels = c("No bridging","CR/PR","SD/PD"))
)
data1 <- IPTW.data %>%
mutate(
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
"Largest lesion" = Largest.lesion,
"HCT-CI" = HCT.CI,
"ALC pre-LD" = ALC.preLD,
"LDH pre-LD" = LDH.preLD/1000,
"Male sex" = ifelse(Sex == "M",1,0),
CRS2.4=ifelse(CRS.grade == 0 | CRS.grade == 1 ,0,1),
"Bridging category" = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD"), levels = c("No bridging","CR/PR","SD/PD"))
)
data2 <- m.data %>%
mutate(
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
"Largest lesion" = Largest.lesion,
"HCT-CI" = HCT.CI,
"ALC pre-LD" = ALC.preLD,
"LDH pre-LD" = LDH.preLD/1000,
"Male sex" = ifelse(Sex == "M",1,0),
CRS2.4=ifelse(CRS.grade == 0 | CRS.grade == 1 ,0,1),
"Bridging category" = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD"), levels = c("No bridging","CR/PR","SD/PD"))
)
uv_tab <- tbl_uvregression(
data0[c(preds)],
method = lm,
y = toci.doses
)
mv_tab<-lm( toci.doses ~ Product + `Largest lesion` + `ALC pre-LD` + Age + `Male sex` + `LDH pre-LD` + `Bridging category`, data0) %>% tbl_regression()
uv_tab_IPTW <- tbl_uvregression(
data1[c(preds)],
method = lm,
y = toci.doses,
method.args = list(weights = data1$weights)
)
mv_tab_IPTW<-lm( toci.doses ~ Product + `Largest lesion` + `ALC pre-LD` + Age + `Male sex` + `LDH pre-LD` + `Bridging category`, data1, weights=weights ) %>%
tbl_regression()
uv_tab_PSM <- tbl_uvregression(
data2[c(preds)],
method = lm,
y = toci.doses,
method.args = list(weights = data2$weights)
)
mv_tab_PSM<-lm( toci.doses ~ Product + `Largest lesion` + `ALC pre-LD` + Age + `Male sex` + `LDH pre-LD` + `Bridging category`, data2, weights=weights ) %>%
tbl_regression()
row1 <- tbl_merge(list(uv_tab, mv_tab), tab_spanner = c("**Univariate**", "**Multivariable**"))
row2 <- tbl_merge(list(uv_tab_IPTW, mv_tab_IPTW))
row3 <- tbl_merge(list(uv_tab_PSM, mv_tab_PSM))
tbl_stack(list(row1, row2, row3), group_header = c("UNWEIGHTED ANALYSIS", "IPTW ANALYSIS", "PSM ANALYSIS"), quiet=TRUE)
| Characteristic |
Univariate
|
Multivariable
|
| N |
Beta |
95% CI |
p-value |
Beta |
95% CI |
p-value |
| UNWEIGHTED ANALYSIS |
| Product |
149 |
|
|
|
|
|
|
| Liso-cel |
|
— |
— |
|
— |
— |
|
| Axi-cel |
|
0.58 |
0.21, 0.95 |
0.002 |
0.37 |
-0.05, 0.78 |
0.080 |
| LDH pre-LD |
148 |
0.17 |
0.02, 0.32 |
0.027 |
0.13 |
-0.02, 0.28 |
0.093 |
| ALC pre-LD |
149 |
-0.04 |
-0.14, 0.05 |
0.4 |
-0.04 |
-0.13, 0.06 |
0.4 |
| Largest lesion |
149 |
0.07 |
0.02, 0.12 |
0.004 |
0.06 |
0.01, 0.11 |
0.026 |
| Age |
149 |
-0.01 |
-0.03, 0.00 |
0.049 |
-0.01 |
-0.02, 0.01 |
0.5 |
| Male sex |
149 |
0.05 |
-0.32, 0.43 |
0.8 |
0.01 |
-0.36, 0.39 |
>0.9 |
| CMV |
149 |
1.1 |
0.77, 1.5 |
<0.001 |
|
|
|
| Bridging category |
145 |
|
|
|
|
|
|
| No bridging |
|
— |
— |
|
— |
— |
|
| CR/PR |
|
-0.50 |
-1.0, 0.03 |
0.064 |
-0.35 |
-0.88, 0.17 |
0.2 |
| SD/PD |
|
0.30 |
-0.13, 0.73 |
0.2 |
0.08 |
-0.38, 0.55 |
0.7 |
| IPTW ANALYSIS |
| Product |
126 |
|
|
|
|
|
|
| Liso-cel |
|
— |
— |
|
— |
— |
|
| Axi-cel |
|
0.36 |
-0.02, 0.73 |
0.062 |
0.25 |
-0.14, 0.65 |
0.2 |
| LDH pre-LD |
125 |
0.18 |
0.01, 0.35 |
0.036 |
0.14 |
-0.03, 0.32 |
0.10 |
| ALC pre-LD |
126 |
-0.04 |
-0.14, 0.06 |
0.5 |
-0.04 |
-0.14, 0.06 |
0.4 |
| Largest lesion |
126 |
0.06 |
0.01, 0.11 |
0.017 |
0.05 |
0.00, 0.10 |
0.049 |
| Age |
126 |
-0.01 |
-0.03, 0.00 |
0.10 |
-0.01 |
-0.02, 0.01 |
0.4 |
| Male sex |
126 |
-0.06 |
-0.43, 0.32 |
0.8 |
-0.07 |
-0.44, 0.31 |
0.7 |
| CMV |
126 |
1.1 |
0.77, 1.5 |
<0.001 |
|
|
|
| Bridging category |
123 |
|
|
|
|
|
|
| No bridging |
|
— |
— |
|
— |
— |
|
| CR/PR |
|
-0.49 |
-0.98, 0.01 |
0.053 |
-0.45 |
-0.94, 0.05 |
0.076 |
| SD/PD |
|
0.24 |
-0.18, 0.66 |
0.3 |
0.02 |
-0.45, 0.48 |
>0.9 |
| PSM ANALYSIS |
| Product |
149 |
|
|
|
|
|
|
| Liso-cel |
|
— |
— |
|
— |
— |
|
| Axi-cel |
|
0.40 |
0.08, 0.72 |
0.015 |
0.34 |
0.00, 0.68 |
0.052 |
| LDH pre-LD |
148 |
0.31 |
-0.07, 0.69 |
0.11 |
0.21 |
-0.19, 0.60 |
0.3 |
| ALC pre-LD |
149 |
0.00 |
-0.08, 0.08 |
>0.9 |
-0.01 |
-0.09, 0.08 |
0.8 |
| Largest lesion |
149 |
0.04 |
-0.01, 0.09 |
0.084 |
0.03 |
-0.03, 0.08 |
0.3 |
| Age |
149 |
-0.01 |
-0.03, 0.00 |
0.077 |
-0.01 |
-0.03, 0.01 |
0.2 |
| Male sex |
149 |
-0.07 |
-0.39, 0.25 |
0.7 |
-0.16 |
-0.48, 0.17 |
0.3 |
| CMV |
149 |
1.1 |
0.81, 1.4 |
<0.001 |
|
|
|
| Bridging category |
144 |
|
|
|
|
|
|
| No bridging |
|
— |
— |
|
— |
— |
|
| CR/PR |
|
-0.59 |
-1.0, -0.17 |
0.006 |
-0.51 |
-0.93, -0.08 |
0.020 |
| SD/PD |
|
0.23 |
-0.17, 0.62 |
0.3 |
0.10 |
-0.36, 0.55 |
0.7 |
Cefepime
Show code
theme_gtsummary_compact()
preds <- c("cefepime.doses","Product", "LDH pre-LD","ALC pre-LD", "Largest lesion", "Age", "Male sex", "CMV", "Bridging category")
data0 <- dataset %>%
mutate(
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
"Largest lesion" = Largest.lesion,
"HCT-CI" = HCT.CI,
"ALC pre-LD" = ALC.preLD,
"LDH pre-LD" = LDH.preLD/1000,
"Male sex" = ifelse(Sex == "M",1,0),
CRS2.4=ifelse(CRS.grade == 0 | CRS.grade == 1 ,0,1),
"Bridging category" = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD"), levels = c("No bridging","CR/PR","SD/PD"))
)
data1 <- IPTW.data %>%
mutate(
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
"Largest lesion" = Largest.lesion,
"HCT-CI" = HCT.CI,
"ALC pre-LD" = ALC.preLD,
"LDH pre-LD" = LDH.preLD/1000,
"Male sex" = ifelse(Sex == "M",1,0),
CRS2.4=ifelse(CRS.grade == 0 | CRS.grade == 1 ,0,1),
"Bridging category" = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD"), levels = c("No bridging","CR/PR","SD/PD"))
)
data2 <- m.data %>%
mutate(
Product = factor(recode(CAR.T.Product.Type, "Yescarta" = "Axi-cel","Breyanzi" = "Liso-cel"), levels = c("Liso-cel","Axi-cel") ),
"Largest lesion" = Largest.lesion,
"HCT-CI" = HCT.CI,
"ALC pre-LD" = ALC.preLD,
"LDH pre-LD" = LDH.preLD/1000,
"Male sex" = ifelse(Sex == "M",1,0),
CRS2.4=ifelse(CRS.grade == 0 | CRS.grade == 1 ,0,1),
"Bridging category" = factor(recode(Bridging.response.category, "0" = "No bridging", "1" = "CR/PR", "2" = "SD/PD"), levels = c("No bridging","CR/PR","SD/PD"))
)
uv_tab <- tbl_uvregression(
data0[c(preds)],
method = lm,
y = cefepime.doses
)
mv_tab<-lm( cefepime.doses ~ Product + `Largest lesion` + `ALC pre-LD` + Age + `Male sex` + `LDH pre-LD` + `Bridging category`, data0) %>% tbl_regression()
uv_tab_IPTW <- tbl_uvregression(
data1[c(preds)],
method = lm,
y = cefepime.doses,
method.args = list(weights = data1$weights)
)
mv_tab_IPTW<-lm( cefepime.doses ~ Product + `Largest lesion` + `ALC pre-LD` + Age + `Male sex` + `LDH pre-LD` + `Bridging category`, data1, weights=weights ) %>%
tbl_regression()
uv_tab_PSM <- tbl_uvregression(
data2[c(preds)],
method = lm,
y = cefepime.doses,
method.args = list(weights = data2$weights)
)
mv_tab_PSM<-lm( cefepime.doses ~ Product + `Largest lesion` + `ALC pre-LD` + Age + `Male sex` + `LDH pre-LD` + `Bridging category`, data2, weights=weights ) %>%
tbl_regression()
row1 <- tbl_merge(list(uv_tab, mv_tab), tab_spanner = c("**Univariate**", "**Multivariable**"))
row2 <- tbl_merge(list(uv_tab_IPTW, mv_tab_IPTW))
row3 <- tbl_merge(list(uv_tab_PSM, mv_tab_PSM))
tbl_stack(list(row1, row2, row3), group_header = c("UNWEIGHTED ANALYSIS", "IPTW ANALYSIS", "PSM ANALYSIS"), quiet=TRUE)
| Characteristic |
Univariate
|
Multivariable
|
| N |
Beta |
95% CI |
p-value |
Beta |
95% CI |
p-value |
| UNWEIGHTED ANALYSIS |
| Product |
149 |
|
|
|
|
|
|
| Liso-cel |
|
— |
— |
|
— |
— |
|
| Axi-cel |
|
4.9 |
2.0, 7.8 |
<0.001 |
4.8 |
1.5, 8.0 |
0.005 |
| LDH pre-LD |
148 |
1.2 |
0.02, 2.4 |
0.046 |
0.95 |
-0.24, 2.2 |
0.12 |
| ALC pre-LD |
149 |
0.58 |
-0.17, 1.3 |
0.13 |
0.79 |
0.03, 1.5 |
0.041 |
| Largest lesion |
149 |
0.19 |
-0.21, 0.60 |
0.3 |
0.06 |
-0.36, 0.49 |
0.8 |
| Age |
149 |
-0.11 |
-0.21, 0.00 |
0.056 |
-0.06 |
-0.17, 0.06 |
0.3 |
| Male sex |
149 |
1.2 |
-1.8, 4.1 |
0.4 |
1.7 |
-1.3, 4.6 |
0.3 |
| CMV |
149 |
3.4 |
0.26, 6.5 |
0.034 |
|
|
|
| Bridging category |
145 |
|
|
|
|
|
|
| No bridging |
|
— |
— |
|
— |
— |
|
| CR/PR |
|
0.31 |
-3.9, 4.6 |
0.9 |
2.0 |
-2.1, 6.2 |
0.3 |
| SD/PD |
|
1.2 |
-2.2, 4.7 |
0.5 |
0.99 |
-2.7, 4.6 |
0.6 |
| IPTW ANALYSIS |
| Product |
126 |
|
|
|
|
|
|
| Liso-cel |
|
— |
— |
|
— |
— |
|
| Axi-cel |
|
4.0 |
1.1, 7.0 |
0.008 |
3.9 |
0.72, 7.1 |
0.017 |
| LDH pre-LD |
125 |
1.3 |
-0.03, 2.7 |
0.056 |
1.1 |
-0.28, 2.5 |
0.12 |
| ALC pre-LD |
126 |
0.62 |
-0.19, 1.4 |
0.13 |
0.78 |
-0.03, 1.6 |
0.060 |
| Largest lesion |
126 |
0.08 |
-0.32, 0.47 |
0.7 |
0.06 |
-0.37, 0.48 |
0.8 |
| Age |
126 |
-0.08 |
-0.19, 0.04 |
0.2 |
-0.07 |
-0.19, 0.05 |
0.2 |
| Male sex |
126 |
0.28 |
-2.7, 3.3 |
0.9 |
0.94 |
-2.1, 4.0 |
0.5 |
| CMV |
126 |
3.4 |
0.29, 6.4 |
0.032 |
|
|
|
| Bridging category |
123 |
|
|
|
|
|
|
| No bridging |
|
— |
— |
|
— |
— |
|
| CR/PR |
|
0.09 |
-4.0, 4.1 |
>0.9 |
1.0 |
-3.0, 5.0 |
0.6 |
| SD/PD |
|
-0.04 |
-3.5, 3.4 |
>0.9 |
-0.27 |
-4.0, 3.5 |
0.9 |
| PSM ANALYSIS |
| Product |
149 |
|
|
|
|
|
|
| Liso-cel |
|
— |
— |
|
— |
— |
|
| Axi-cel |
|
3.8 |
1.0, 6.6 |
0.008 |
4.0 |
0.96, 7.0 |
0.010 |
| LDH pre-LD |
148 |
3.8 |
0.44, 7.1 |
0.027 |
2.8 |
-0.64, 6.3 |
0.11 |
| ALC pre-LD |
149 |
0.71 |
0.00, 1.4 |
0.051 |
0.83 |
0.09, 1.6 |
0.028 |
| Largest lesion |
149 |
0.16 |
-0.27, 0.59 |
0.5 |
-0.01 |
-0.47, 0.45 |
>0.9 |
| Age |
149 |
-0.11 |
-0.25, 0.03 |
0.14 |
-0.11 |
-0.26, 0.04 |
0.2 |
| Male sex |
149 |
1.1 |
-1.7, 3.9 |
0.4 |
1.2 |
-1.7, 4.0 |
0.4 |
| CMV |
149 |
4.9 |
1.8, 8.0 |
0.002 |
|
|
|
| Bridging category |
144 |
|
|
|
|
|
|
| No bridging |
|
— |
— |
|
— |
— |
|
| CR/PR |
|
-1.5 |
-5.3, 2.3 |
0.4 |
-0.85 |
-4.6, 2.9 |
0.7 |
| SD/PD |
|
0.45 |
-3.1, 4.0 |
0.8 |
-0.44 |
-4.4, 3.6 |
0.8 |
PROBABILITY PLOTS
Response based on labs and imaging
Probability of CR: LDH pre-LD, stratified by product
Show code
data1 <- filter(dataset, Infused == 1) %>%
mutate(
CAR.T.Product.Type = recode(CAR.T.Product.Type, "Breyanzi"="Liso-cel","Yescarta"="Axi-cel")
)
dd <- datadist(data1)
options(datadist='dd')
fit <- lrm(Best.CR ~ CAR.T.Product.Type * LDH.preLD, data=data1)
data.frame(Predict(fit,LDH.preLD,CAR.T.Product.Type,fun = plogis)) %>%
ggplot() +
geom_line(aes(x=LDH.preLD,y=yhat,col=CAR.T.Product.Type)) +
geom_ribbon(aes(x=LDH.preLD,ymin=lower, ymax=upper,fill=CAR.T.Product.Type),alpha=0.10)+
labs(x = "LDH pre-LD (U/L)",
y = "Probability of CR")+
#scale_x_continuous(labels = alc_breaks,breaks = c(-.5,-.25,0,.25))+
#ggtitle("Figure.")+
theme_bw() +
theme(title = element_text(size=16,face="bold"),legend.title=element_blank()) +
ylim(0,1)

Probability of CR: largest lesion, stratified by product
Show code
data1 <- filter(dataset, Infused == 1) %>%
mutate(
CAR.T.Product.Type = recode(CAR.T.Product.Type, "Breyanzi"="Liso-cel","Yescarta"="Axi-cel")
)
dd <- datadist(data1)
options(datadist='dd')
fit <- lrm(Best.CR ~ CAR.T.Product.Type*Largest.lesion, data=data1)
data.frame(Predict(fit,Largest.lesion,CAR.T.Product.Type,fun = plogis)) %>%
ggplot() +
geom_line(aes(x=Largest.lesion,y=yhat,col=CAR.T.Product.Type)) +
geom_ribbon(aes(x=Largest.lesion,ymin=lower, ymax=upper,fill=CAR.T.Product.Type),alpha=0.10)+
labs(x = "Largest lesion (cm)",
y = "Probability of CR")+
#scale_x_continuous(labels = alc_breaks,breaks = c(-.5,-.25,0,.25))+
#ggtitle("Figure.")+
theme_bw() +
theme(title = element_text(size=16,face="bold"),legend.title=element_blank()) +
ylim(0,1)

Probability of CR and PD: ALC (RCS)
Show code
data1 <- filter(dataset, Infused == 1)
dd <- datadist(data1)
options(datadist='dd')
fit <- lrm(Best.CR ~ rcs(ALC.preLD,3), data=data1)
df1 <- data.frame(Predict(fit,ALC.preLD,fun = plogis))
fit2 <- lrm(Best.PD ~ rcs(ALC.preLD,3), data=data1)
df2 <- data.frame(Predict(fit2,ALC.preLD,fun = plogis))
ggplot() +
geom_line(data=df1, aes(x=ALC.preLD,y=yhat, color = "CR")) + geom_ribbon( data=df1, aes(x=ALC.preLD,ymin=lower, ymax=upper),alpha=0.10)+
geom_line(data=df2, aes(x=ALC.preLD,y=yhat, color ="PD" )) + geom_ribbon(data = df2, aes(x=ALC.preLD,ymin=lower, ymax=upper),alpha=0.10)+
labs(x = "ALC pre-LD (10\U00B3/\U00B5L)",
y = "Probability")+
theme_bw() +
scale_y_continuous(breaks=c(0,0.2,0.4,0.6,0.8,1.0), limits=c(0, 1)) +
scale_x_continuous(breaks=c(0.25,0.5,0.75,1.0,1.25,1.5,1.75), limits=c(0.25, 1.75)) +
theme(legend.position = c(0, 1),legend.justification = c(-9, 1.1))+
scale_color_manual(values = c ("steelblue","coral2")) +
theme(title = element_text(size=20,face="bold"),legend.title=element_blank())

Hazard of PFS: LDH pre-LD
Show code
data1 <- filter(dataset, Infused == 1)
S <- Surv(data1$Days.to.relapse.death.or.DLC, data1$Relapse.or.death)
f <- cph(S ~ LDH.preLD * CAR.T.Product.Type, x=TRUE, y=TRUE,surv=TRUE,data=data1)
model <- Predict(f, CAR.T.Product.Type, LDH.preLD, fun=function(x) exp(x) )
ggplot(as.data.frame(model),aes(x=LDH.preLD, y=yhat, z = CAR.T.Product.Type)) +
geom_line(
aes(col = CAR.T.Product.Type)
) +
geom_ribbon(data = model, aes(ymin=lower, ymax=upper), alpha=0.2, linetype=0) +
theme_bw() +
labs(
#title = "Survival by product and LDH pre-LD",
x = "LDH pre-LD (U/L)",
y = "PFS (hazard)") +
theme(title = element_text(size=16,face="bold"),legend.title=element_blank())

Probability of CR and PD: LDH pre-LD
Show code
data1 <- filter(dataset, Infused == 1)
dd <- datadist(data1)
options(datadist='dd')
fit <- lrm(Best.CR ~ LDH.preLD, data=data1)
df1 <- data.frame(Predict(fit,LDH.preLD,fun = plogis))
fit2 <- lrm(Best.PD ~ LDH.preLD, data=data1)
df2 <- data.frame(Predict(fit2,LDH.preLD,fun = plogis))
ggplot() +
geom_line(data=df1, aes(x=LDH.preLD,y=yhat, color = "CR")) + geom_ribbon( data=df1, aes(x=LDH.preLD,ymin=lower, ymax=upper),alpha=0.10)+
geom_line(data=df2, aes(x=LDH.preLD,y=yhat, color ="PD" )) + geom_ribbon(data = df2, aes(x=LDH.preLD,ymin=lower, ymax=upper),alpha=0.10)+
labs(x = "LDH pre-LD (U/L)",
y = "Probability")+
theme_classic() +
scale_y_continuous(breaks=c(0,0.2,0.4,0.6,0.8,1.0), limits=c(0, 1)) +
#scale_x_continuous(breaks=c(0.25,0.5,0.75,1.0,1.25,1.5,1.75), limits=c(0.25, 1.75)) +
theme(legend.position = c(0, 1),legend.justification = c(-9, 1.1))+
scale_color_manual(values = c ("steelblue","coral2")) +
theme(title = element_text(size=20,face="bold"),legend.title=element_blank())

Probability of CR: LDH pre-LD
Show code
data1 <- filter(dataset, Infused == 1)
dd <- datadist(data1)
options(datadist='dd')
fit <- lrm(Best.CR ~ rcs(LDH.preLD,3), data=data1)
data.frame(Predict(fit,LDH.preLD,fun = plogis)) %>%
ggplot() +
geom_line(aes(x=LDH.preLD,y=yhat)) +
geom_ribbon(aes(x=LDH.preLD,ymin=lower, ymax=upper),alpha=0.10)+
labs(x = "LDH pre-LD (U/L)",
y = "Probability of CR")+
#scale_x_continuous(labels = alc_breaks,breaks = c(-.5,-.25,0,.25))+
#ggtitle("Figure.")+
ylim(0,1) +
theme_classic() +
theme(title = element_text(size=16,face="bold"),legend.title=element_blank())

Probability of CR: largest Lesion size, stratified by product
Show code
data1 <- filter(dataset, Infused == 1)
dd <- datadist(data1)
options(datadist='dd')
fit <- lrm(Best.CR ~ CAR.T.Product.Type * rcs(Largest.lesion,3), data=data1)
data.frame(Predict(fit,Largest.lesion,CAR.T.Product.Type,fun = plogis)) %>%
ggplot() +
geom_line(aes(x=Largest.lesion ,y=yhat,col=CAR.T.Product.Type)) +
geom_ribbon(aes(x=Largest.lesion ,ymin=lower, ymax=upper,fill=CAR.T.Product.Type),alpha=0.10)+
labs(x = "Largest lesion (cm)",
y = "Probability of CR")+
theme_bw() +
theme(title = element_text(size=16,face="bold"),legend.title=element_blank())

Probability of CR: Largest Lesion size (RCS)
Show code
data1 <- filter(dataset, Infused == 1)
dd <- datadist(data1)
options(datadist='dd')
fit <- lrm(Best.CR ~ rcs(Largest.lesion,3), data=data1)
data.frame(Predict(fit,Largest.lesion,fun = plogis)) %>%
ggplot() +
geom_line(aes(x=Largest.lesion ,y=yhat)) +
geom_ribbon(aes(x=Largest.lesion ,ymin=lower, ymax=upper),alpha=0.10)+
labs(x = "Largest lesion (cm)",
y = "Probability of CR")+
ylim(0,1) +
theme_classic() +
theme(title = element_text(size=16,face="bold"),legend.title=element_blank())

Ferritin!
Probability of ICANS based on day 3 ferritin
Show code
data1 <- filter(dataset, Infused == 1) %>%
mutate(
ICANS0 = ifelse( ICANS.grade==0,1,0),
ICANS1.2 = ifelse( ICANS.grade==1 | ICANS.grade == 2,1,0),
ICANS.any.grade = ifelse( ICANS.grade != 0 ,1,0),
ICANS3.4 = ifelse( ICANS.grade==3 | ICANS.grade == 4,1,0),
ferritin.ratio = log(ferritin.d3 / ferritin.d0),
ferritin.d3 = log10(ferritin.d3)
)
dd <- datadist(data1)
options(datadist='dd')
fit <- lrm(ICANS0 ~ ferritin.d3 + CAR.T.Product.Type, data=data1)
df1 <- data.frame(Predict(fit,ferritin.d3,fun = plogis))
fit2 <- lrm(ICANS1.2 ~ ferritin.d3 + CAR.T.Product.Type, data=data1)
df2 <- data.frame(Predict(fit2,ferritin.d3,fun = plogis))
fit3 <- lrm(ICANS3.4 ~ ferritin.d3 + CAR.T.Product.Type, data=data1)
df3 <- data.frame(Predict(fit3,ferritin.d3,fun = plogis))
ggplot() +
geom_line(data=df1, aes(x=ferritin.d3,y=yhat, color = "G0 ICANS")) + geom_ribbon( data=df1, aes(x=ferritin.d3,ymin=lower, ymax=upper),alpha=0.10)+
geom_line(data=df2, aes(x=ferritin.d3,y=yhat, color ="G1-2 ICANS" )) + geom_ribbon(data = df2, aes(x=ferritin.d3,ymin=lower, ymax=upper),alpha=0.10)+
geom_line(data=df3, aes(x=ferritin.d3,y=yhat, color ="G\u22653 ICANS" )) + geom_ribbon(data = df3, aes(x=ferritin.d3,ymin=lower, ymax=upper),alpha=0.10)+
labs(x = "log(ferritin, day 3) (ng/mL)",
y = "Probability")+
theme_bw() +
scale_y_continuous(breaks=c(0,0.2,0.4,0.6,0.8,1.0), limits=c(0, 1)) +
#theme(legend.position = c(0, 1),legend.justification = c(-4.5, 1.1))+
scale_color_manual(values = c ("steelblue","coral2","purple")) +
theme(title = element_text(size=20,face="bold"),legend.title=element_blank())

Probability of CRS based on day 3 ferritin
Show code
data1 <- filter(dataset, Infused == 1) %>%
mutate(
ICANS0 = ifelse( ICANS.grade==0,1,0),
ICANS1.2 = ifelse( ICANS.grade==1 | ICANS.grade == 2,1,0),
ICANS.any.grade = ifelse( ICANS.grade != 0 ,1,0),
ICANS3.4 = ifelse( ICANS.grade==3 | ICANS.grade == 4,1,0),
CRS0 = ifelse( CRS.grade==0,1,0),
CRS1.2 = ifelse( CRS.grade==1 | CRS.grade == 2,1,0),
CRS.any.grade = ifelse( CRS.grade != 0 ,1,0),
CRS3.4 = ifelse( CRS.grade==3 | CRS.grade == 4,1,0),
ferritin.ratio = log(ferritin.d3 / ferritin.d0),
ferritin.d3 = log10(ferritin.d3)
)
dd <- datadist(data1)
options(datadist='dd')
fit <- lrm(CRS0 ~ ferritin.d3 + CAR.T.Product.Type, data=data1)
df1 <- data.frame(Predict(fit,ferritin.d3,fun = plogis))
fit2 <- lrm(CRS1.2 ~ ferritin.d3 + CAR.T.Product.Type, data=data1)
df2 <- data.frame(Predict(fit2,ferritin.d3,fun = plogis))
fit3 <- lrm(CRS3.4 ~ ferritin.d3 + CAR.T.Product.Type, data=data1)
df3 <- data.frame(Predict(fit3,ferritin.d3,fun = plogis))
ggplot() +
geom_line(data=df1, aes(x=ferritin.d3,y=yhat, color = "G0 CRS")) + geom_ribbon( data=df1, aes(x=ferritin.d3,ymin=lower, ymax=upper),alpha=0.10)+
geom_line(data=df2, aes(x=ferritin.d3,y=yhat, color ="G1-2 CRS" )) + geom_ribbon(data = df2, aes(x=ferritin.d3,ymin=lower, ymax=upper),alpha=0.10)+
geom_line(data=df3, aes(x=ferritin.d3,y=yhat, color ="G\u22653 CRS" )) + geom_ribbon(data = df3, aes(x=ferritin.d3,ymin=lower, ymax=upper),alpha=0.10)+
labs(x = "log(ferritin, day 3) (ng/mL)",
y = "Probability")+
theme_bw() +
scale_y_continuous(breaks=c(0,0.2,0.4,0.6,0.8,1.0), limits=c(0, 1)) +
#theme(legend.position = c(0, 1),legend.justification = c(-4.5, 1.1))+
scale_color_manual(values = c ("steelblue","coral2","purple")) +
theme(title = element_text(size=20,face="bold"),legend.title=element_blank())

Probability of RESPONSE based on day 3 ferritin
Show code
data1 <- filter(dataset, Infused == 1) %>%
mutate(
ICANS0 = ifelse( ICANS.grade==0,1,0),
ICANS1.2 = ifelse( ICANS.grade==1 | ICANS.grade == 2,1,0),
ICANS.any.grade = ifelse( ICANS.grade != 0 ,1,0),
ICANS3.4 = ifelse( ICANS.grade==3 | ICANS.grade == 4,1,0),
CRS0 = ifelse( CRS.grade==0,1,0),
CRS1.2 = ifelse( CRS.grade==1 | CRS.grade == 2,1,0),
CRS.any.grade = ifelse( CRS.grade != 0 ,1,0),
CRS3.4 = ifelse( CRS.grade==3 | CRS.grade == 4,1,0),
ferritin.ratio = log(ferritin.d3 / ferritin.d0),
ferritin.d3 = log10(ferritin.d3)
)
dd <- datadist(data1)
options(datadist='dd')
fit <- lrm(Best.CR ~ ferritin.d3 + CAR.T.Product.Type, data=data1)
df1 <- data.frame(Predict(fit,ferritin.d3,fun = plogis))
fit2 <- lrm(Best.PR ~ ferritin.d3 + CAR.T.Product.Type, data=data1)
df2 <- data.frame(Predict(fit2,ferritin.d3,fun = plogis))
fit3 <- lrm(Best.PD ~ ferritin.d3 + CAR.T.Product.Type, data=data1)
df3 <- data.frame(Predict(fit3,ferritin.d3,fun = plogis))
ggplot() +
geom_line(data=df1, aes(x=ferritin.d3,y=yhat, color = "CR")) + geom_ribbon( data=df1, aes(x=ferritin.d3,ymin=lower, ymax=upper),alpha=0.10)+
geom_line(data=df2, aes(x=ferritin.d3,y=yhat, color ="PR" )) + geom_ribbon(data = df2, aes(x=ferritin.d3,ymin=lower, ymax=upper),alpha=0.10)+
geom_line(data=df3, aes(x=ferritin.d3,y=yhat, color ="PD" )) + geom_ribbon(data = df3, aes(x=ferritin.d3,ymin=lower, ymax=upper),alpha=0.10)+
labs(x = "log(ferritin, day 3) (ng/mL)",
y = "Probability")+
theme_bw() +
scale_y_continuous(breaks=c(0,0.2,0.4,0.6,0.8,1.0), limits=c(0, 1)) +
#theme(legend.position = c(0, 1),legend.justification = c(-8.5, 1.1))+
scale_color_manual(values = c ("steelblue","coral2","purple")) +
theme(title = element_text(size=20,face="bold"),legend.title=element_blank())

Probability of CR or PD based on day 3 ferritin - RESTRICTED CUBIC SPLINES model
Show code
data1 <- filter(dataset, Infused == 1) %>%
mutate(
ICANS0.2 = ifelse( as.numeric(ICANS.grade)<=2,1,0),
ICANS.any.grade = ifelse( ICANS.grade != 0 ,1,0),
ICANS3.4 = ifelse( ICANS.grade ==3 | ICANS.grade == 4,1,0),
ferritin.ratio = ferritin.d3 / ferritin.d0
#ferritin.d3 = log(ferritin.d3)
)
dd <- datadist(data1)
options(datadist='dd')
fit <- lrm(Best.CR ~ rcs(ferritin.d3,3), data=data1)
df1 <- data.frame(Predict(fit,ferritin.d3,fun = plogis))
fit2 <- lrm(Best.PD ~ rcs(ferritin.d3,3), data=data1)
df2 <- data.frame(Predict(fit2,ferritin.d3,fun = plogis))
ggplot() +
geom_line(data=df1, aes(x=ferritin.d3,y=yhat, color = "CR")) + geom_ribbon( data=df1, aes(x=ferritin.d3,ymin=lower, ymax=upper),alpha=0.10)+
geom_line(data=df2, aes(x=ferritin.d3,y=yhat, color ="PD" )) + geom_ribbon(data = df2, aes(x=ferritin.d3,ymin=lower, ymax=upper),alpha=0.10)+
labs(x = "Ferritin, day 3 (ng/mL)",
y = "Probability")+
theme_bw() +
scale_y_continuous(breaks=c(0,0.2,0.4,0.6,0.8,1.0), limits=c(0, 1)) +
#scale_x_continuous(breaks=c(0.25,0.5,0.75,1.0,1.25,1.5,1.75), limits=c(0.25, 1.75)) +
#theme(legend.position = c(0, 1),legend.justification = c(-9, 1.1))+
scale_color_manual(values = c ("steelblue","coral2")) +
theme(title = element_text(size=20,face="bold"),legend.title=element_blank())

Hazard of OS and PFS: D3 ferritin
Show code
data1 <- filter(dataset, Infused == 1) %>%
mutate(
ferritin.d3 = log10(ferritin.d3)
)
dd <- datadist(data1)
options(datadist='dd')
S1 <- Surv(data1$Days.to.DLC, data1$Death)
f1 <- cph(S1 ~ ferritin.d3 , x=TRUE, y=TRUE,surv=TRUE,data=data1)
model1 <- Predict(f1, ferritin.d3, fun=function(x) exp(x) )
S2 <- Surv(data1$Days.to.relapse.death.or.DLC, data1$Relapse.or.death)
f2 <- cph(S2 ~ ferritin.d3 , x=TRUE, y=TRUE,surv=TRUE,data=data1)
model2 <- Predict(f2, ferritin.d3, fun=function(x) exp(x) )
ggplot() +
geom_line(data=model1, aes(x=ferritin.d3, y=yhat, color = "OS")) + geom_ribbon(data = model1, aes(x=ferritin.d3, ymin=lower, ymax=upper), alpha=0.1) +
geom_line(data=model2, aes(x=ferritin.d3, y=yhat, color = "PFS")) + geom_ribbon(data = model2, aes(x=ferritin.d3, ymin=lower, ymax=upper), alpha=0.1) +
theme_bw() +
labs(
#title = "Survival by product and ferritin at day 3",
x = "log(ferritin, day 3)",
y = "Hazard") +
#theme(legend.position = c(0, 1),legend.justification = c(-0.8, 1.2))+
scale_color_manual(values = c ("coral2","steelblue")) +
theme(title = element_text(size=20,face="bold"),legend.title=element_blank())

Hazard of PFS: D3 ferritin
Show code
data1 <- filter(dataset, Infused == 1) %>%
mutate(
ferritin.d3 = log10(ferritin.d3)
)
dd <- datadist(data1)
options(datadist='dd')
S <- Surv(data1$Days.to.relapse.death.or.DLC, data1$Relapse.or.death)
f <- cph(S ~ ferritin.d3 , x=TRUE, y=TRUE,surv=TRUE,data=data1)
model <- Predict(f, ferritin.d3, fun=function(x) exp(x) )
ggplot(as.data.frame(model),aes(x=ferritin.d3, y=yhat)) +
geom_line(
aes()
) +
geom_ribbon(data = model, aes(ymin=lower, ymax=upper), alpha=0.2, linetype=0) +
theme_bw() +
labs(
#title = "Survival by product and ferritin at day 3",
x = "log(ferritin), day 3",
y = "PFS (hazard)") +
theme(title = element_text(size=16,face="bold"),legend.title=element_blank())

Hazard of PFS: D3 ferritin - stratified by CAR-T-product
Show code
data1 <- filter(dataset, Infused == 1) %>%
mutate(
ferritin.d3 = log10(ferritin.d3)
)
dd <- datadist(data1)
options(datadist='dd')
S <- Surv(data1$Days.to.relapse.death.or.DLC, data1$Relapse.or.death)
f <- cph(S ~ ferritin.d3 + CAR.T.Product.Type , x=TRUE, y=TRUE,surv=TRUE,data=data1)
model <- Predict(f, CAR.T.Product.Type, ferritin.d3, fun=function(x) exp(x) )
ggplot(as.data.frame(model),aes(x=ferritin.d3, y=yhat, z = CAR.T.Product.Type)) +
geom_line(
aes(col = CAR.T.Product.Type)
) +
geom_ribbon(data = model, aes(ymin=lower, ymax=upper), alpha=0.2, linetype=0) +
theme_bw() +
labs(
#title = "Survival by product and ferritin at day 3",
x = "log(ferritin), day 3",
y = "PFS (hazard)") +
theme(title = element_text(size=16,face="bold"),legend.title=element_blank())

ICANS/CRS
Probability of Grade 0-2 and Grade 3-4 ICANS: LDH pre-LD (RCS)
Show code
data1 <- filter(dataset, Infused == 1) %>%
mutate(
ICANS0.2 = ifelse( ICANS.grade == 2 | ICANS.grade == 1 | ICANS.grade == 0,1,0),
ICANS3.4 = ifelse( ICANS.grade == 3 | ICANS.grade == 4,1,0)
#ferritin.d3 = log(ferritin.d3)
)
dd <- datadist(data1)
options(datadist='dd')
fit <- lrm(ICANS0.2 ~ rcs(LDH.preLD,3), data=data1)
df1 <- data.frame(Predict(fit,LDH.preLD,fun = plogis))
fit2 <- lrm(ICANS3.4 ~ rcs(LDH.preLD,3), data=data1)
df2 <- data.frame(Predict(fit2,LDH.preLD,fun = plogis))
ggplot() +
geom_line(data=df1, aes(x=LDH.preLD,y=yhat, color = "0-2")) + geom_ribbon( data=df1, aes(x=LDH.preLD,ymin=lower, ymax=upper),alpha=0.10)+
geom_line(data=df2, aes(x=LDH.preLD,y=yhat, color ="3-4" )) + geom_ribbon(data = df2, aes(x=LDH.preLD,ymin=lower, ymax=upper),alpha=0.10)+
labs(x = "LDH pre-LD (U/L)",
y = "Probability")+
theme_bw() +
scale_y_continuous(breaks=c(0,0.2,0.4,0.6,0.8,1.0), limits=c(0, 1)) +
#scale_x_continuous(breaks=c(0.25,0.5,0.75,1.0,1.25,1.5,1.75), limits=c(0.25, 1.75)) +
#theme(legend.position = c(0, 1),legend.justification = c(-9, 1.1))+
scale_color_manual(values = c ("steelblue","coral2")) +
theme(title = element_text(size=20,face="bold"),legend.title=element_blank())

Probability of any grade CRS based on Age
Show code
data1 <- filter(dataset, Infused == 1) %>%
select(CRS.grade, ICANS.grade, Age, CAR.T.Product.Type) %>%
mutate(
CRS.any = ifelse( CRS.grade != 0,1,0),
ICANS.any = ifelse( ICANS.grade !=0,1,0)
)
dd <- datadist(data1)
options(datadist='dd')
fit <- lrm(CRS.any ~ CAR.T.Product.Type *Age, data=data1)
data.frame(Predict(fit,Age,CAR.T.Product.Type,fun = plogis)) %>%
ggplot() +
geom_line(aes(x=Age,y=yhat,col=CAR.T.Product.Type)) +
geom_ribbon(aes(x=Age,ymin=lower, ymax=upper,fill=CAR.T.Product.Type),alpha=0.10)+
labs(x = "Age (years)",
y = "Probability of any grade CRS")+
theme_bw() +
theme(title = element_text(size=16,face="bold"),legend.title=element_blank())

Probability of any grade ICANS based on Age
Show code
data1 <- filter(dataset, Infused == 1) %>%
select(CRS.grade, ICANS.grade, Age, CAR.T.Product.Type) %>%
mutate(
CRS.any = ifelse( CRS.grade != 0,1,0),
ICANS.any = ifelse( ICANS.grade !=0,1,0)
)
dd <- datadist(data1)
options(datadist='dd')
dd <- datadist(data1)
options(datadist='dd')
fit <- lrm(ICANS.any ~ CAR.T.Product.Type * Age, data=data1)
data.frame(Predict(fit,Age,CAR.T.Product.Type,fun = plogis)) %>%
ggplot() +
geom_line(aes(x=Age,y=yhat,col=CAR.T.Product.Type)) +
geom_ribbon(aes(x=Age,ymin=lower, ymax=upper,fill=CAR.T.Product.Type),alpha=0.10)+
labs(x = "Age (years)",
y = "Probability of any grade ICANS")+
#scale_x_continuous(labels = alc_breaks,breaks = c(-.5,-.25,0,.25))+
#ggtitle("Figure.")+
theme_bw() +
theme(title = element_text(size=16,face="bold"),legend.title=element_blank())

Probability of Any grade and G3+ CRS: Age
Show code
data1 <- filter(dataset, Infused == 1) %>%
select(CRS.grade, ICANS.grade, Age, CAR.T.Product.Type) %>%
mutate(
CRS3.4 = ifelse( CRS.grade == 3 | CRS.grade == 4,1,0),
ICANS3.4 = ifelse( ICANS.grade == 3 | ICANS.grade == 4,1,0),
CRS.any = ifelse( CRS.grade !=0 ,1,0),
ICANS.any = ifelse( ICANS.grade !=0,1,0)
)
dd <- datadist(data1)
options(datadist='dd')
fit1 <- lrm(CRS3.4 ~ CAR.T.Product.Type + Age, data=data1)
df1 <- data.frame(Predict(fit1,Age,fun = plogis))
fit2 <- lrm(CRS.any ~ CAR.T.Product.Type + Age, data=data1)
df2 <- data.frame(Predict(fit2,Age,fun = plogis))
ggplot() +
geom_line(data=df1, aes(x=Age,y=yhat, color = "\u22653")) + geom_ribbon( data=df1, aes(x=Age,ymin=lower, ymax=upper),alpha=0.10)+
geom_line(data=df2, aes(x=Age,y=yhat, color ="Any" )) + geom_ribbon(data = df2, aes(x=Age,ymin=lower, ymax=upper),alpha=0.10)+
labs(x = "Age (years)",
y = "Probability of CRS")+
theme_bw() +
scale_y_continuous(breaks=c(0,0.2,0.4,0.6,0.8,1.0), limits=c(0, 1)) +
#scale_x_continuous(breaks=c(0.25,0.5,0.75,1.0,1.25,1.5,1.75), limits=c(0.25, 1.75)) +
#theme(legend.position = c(0, 1),legend.justification = c(-8.3, 3))+
scale_color_manual(values = c ("coral2","steelblue")) +
theme(title = element_text(size=20,face="bold"),legend.title=element_blank())

Probability of any grade and 3+ ICANS: Age
Show code
data1 <- filter(dataset, Infused == 1) %>%
select(CRS.grade, ICANS.grade, Age, CAR.T.Product.Type) %>%
mutate(
CRS3.4 = ifelse( CRS.grade == 3 | CRS.grade == 4,1,0),
ICANS3.4 = ifelse( ICANS.grade == 3 | ICANS.grade == 4,1,0),
CRS.any = ifelse( CRS.grade !=0 ,1,0),
ICANS.any = ifelse( ICANS.grade !=0,1,0)
)
dd <- datadist(data1)
options(datadist='dd')
fit1 <- lrm(ICANS3.4 ~ CAR.T.Product.Type + Age, data=data1)
df1 <- data.frame(Predict(fit1,Age,fun = plogis))
fit2 <- lrm(ICANS.any ~ CAR.T.Product.Type + Age, data=data1)
df2 <- data.frame(Predict(fit2,Age,fun = plogis))
ggplot() +
geom_line(data=df1, aes(x=Age,y=yhat, color = "\u22653")) + geom_ribbon( data=df1, aes(x=Age,ymin=lower, ymax=upper),alpha=0.10)+
geom_line(data=df2, aes(x=Age,y=yhat, color ="Any" )) + geom_ribbon(data = df2, aes(x=Age,ymin=lower, ymax=upper),alpha=0.10)+
labs(x = "Age (years)",
y = "Probability of ICANS")+
theme_bw() +
scale_y_continuous(breaks=c(0,0.2,0.4,0.6,0.8,1.0), limits=c(0, 1)) +
#scale_x_continuous(breaks=c(0.25,0.5,0.75,1.0,1.25,1.5,1.75), limits=c(0.25, 1.75)) +
#theme(legend.position = c(0, 1),legend.justification = c(-8.3, 1.1))+
scale_color_manual(values = c ("coral2","steelblue")) +
theme(title = element_text(size=20,face="bold"),legend.title=element_blank())

PFS & OS
Hazard of PFS: LDH - stratified by bulky status
Show code
data1 <- filter(dataset, Infused == 1) %>%
mutate(
Bulky = recode(Bulky, "1"="Bulky","0"="Not bulky")
)
dd <- datadist(data1)
options(datadist='dd')
S <- Surv(data1$Days.to.relapse.death.or.DLC, data1$Relapse.or.death)
f <- cph(S ~ LDH.preLD * Bulky , x=TRUE, y=TRUE,surv=TRUE,data=data1)
med <- Quantile(f)
model <- Predict(f, Bulky, LDH.preLD, fun=function(x) exp(x) )
ggplot(as.data.frame(model),aes(x=LDH.preLD , y=yhat, z = Bulky)) +
geom_line(
aes(col = Bulky)
) +
geom_ribbon(data = model, aes(ymin=lower, ymax=upper), alpha=0.2, linetype=0) +
theme_bw() +
labs(
#title = "Survival by CAR-T product and ALC pre-LD",
x = "LDH pre-LD (U/L)",
y = "PFS (hazard)")+
theme(title = element_text(size=16,face="bold"),legend.title=element_blank())

Hazard of OS: LDH - stratified by bulky status
Show code
data1 <- filter(dataset, Infused == 1) %>%
mutate(
Bulky = recode(Bulky, "1"="Bulky","0"="Not bulky")
)
dd <- datadist(data1)
options(datadist='dd')
S <- Surv(data1$Days.to.DLC, data1$Death)
f <- cph(S ~ LDH.preLD * Bulky , x=TRUE, y=TRUE,surv=TRUE,data=data1)
med <- Quantile(f)
model <- Predict(f, Bulky, LDH.preLD, fun=function(x) exp(x) )
ggplot(as.data.frame(model),aes(x=LDH.preLD , y=yhat, z = Bulky)) +
geom_line(
aes(col = Bulky)
) +
geom_ribbon(data = model, aes(ymin=lower, ymax=upper), alpha=0.2, linetype=0) +
theme_bw() +
labs(
#title = "Survival by CAR-T product and ALC pre-LD",
x = "LDH pre-LD (U/L)",
y = "OS (hazard)")+
theme(title = element_text(size=16,face="bold"),legend.title=element_blank())

Hazard of OS: LDH, stratified
Show code
data1 <- filter(dataset, Infused == 1)
dd <- datadist(data1)
options(datadist='dd')
S <- Surv(data1$Days.to.DLC, data1$Death)
f <- cph(S ~ LDH.preLD , x=TRUE, y=TRUE,surv=TRUE,data=data1)
med <- Quantile(f)
model <- Predict(f, LDH.preLD, fun=function(x) exp(x) )
ggplot(as.data.frame(model),aes(x=LDH.preLD , y=yhat)) +
geom_line() +
geom_ribbon(data = model, aes(ymin=lower, ymax=upper), alpha=0.2, linetype=0) +
theme_bw() +
labs(
#title = "Survival by LDH pre-LD",
x = "LDH pre-LD (U/L)",
y = "OS (hazard)")+
theme(title = element_text(size=16,face="bold"),legend.title=element_blank())

Hazard of PFS: LDH, stratified by product
Show code
data1 <- filter(dataset, Infused == 1)
dd <- datadist(data1)
options(datadist='dd')
S <- Surv(data1$Days.to.relapse.death.or.DLC, data1$Relapse.or.death)
f <- cph(S ~ LDH.preLD * CAR.T.Product.Type , x=TRUE, y=TRUE,surv=TRUE,data=data1)
model <- Predict(f, CAR.T.Product.Type, LDH.preLD, fun=function(x) exp(x) )
ggplot(as.data.frame(model),aes(x=LDH.preLD, y=yhat, z = CAR.T.Product.Type)) +
geom_line(
aes(col = CAR.T.Product.Type)
) +
geom_ribbon(data = model, aes(ymin=lower, ymax=upper), alpha=0.2, linetype=0) +
theme_bw() +
labs(
#title = "Survival by product and LDH pre-LD",
x = "LDH pre-LD (U/L)",
y = "PFS (hazard)") +
theme(title = element_text(size=16,face="bold"),legend.title=element_blank())

Hazard of PFS: LDH, stratified by bulky status
Show code
data1 <- filter(dataset, Infused == 1) %>%
mutate(
Bulky = recode(Bulky,"1"="Bulky","0"="Not bulky")
)
dd <- datadist(data1)
options(datadist='dd')
S <- Surv(data1$Days.to.relapse.death.or.DLC, data1$Relapse.or.death)
f <- cph(S ~ LDH.preLD * Bulky , x=TRUE, y=TRUE,surv=TRUE,data=data1)
model <- Predict(f, Bulky, LDH.preLD, fun=function(x) exp(x) )
ggplot(as.data.frame(model),aes(x=LDH.preLD, y=yhat, z = Bulky)) +
geom_line(
aes(col = Bulky)
) +
geom_ribbon(data = model, aes(ymin=lower, ymax=upper), alpha=0.2, linetype=0) +
theme_bw() +
labs(
#title = "Survival by product and LDH pre-LD",
x = "LDH pre-LD (U/L)",
y = "PFS (hazard)") +
theme(title = element_text(size=16,face="bold"),legend.title=element_blank())

Hazard of OS: LDH, stratified by bulky status
Show code
data1 <- filter(dataset, Infused == 1)%>%
mutate(
Bulky = recode(Bulky,"1"="Bulky","0"="Not bulky")
)
dd <- datadist(data1)
options(datadist='dd')
S <- Surv(data1$Days.to.DLC, data1$Death)
f <- cph(S ~ LDH.preLD * Bulky , x=TRUE, y=TRUE,surv=TRUE,data=data1)
model <- Predict(f, Bulky, LDH.preLD, fun=function(x) exp(x) )
ggplot(as.data.frame(model),aes(x=LDH.preLD, y=yhat, z = Bulky)) +
geom_line(
aes(col = Bulky)
) +
geom_ribbon(data = model, aes(ymin=lower, ymax=upper), alpha=0.2, linetype=0) +
theme_bw() +
labs(
#title = "Survival by product and LDH pre-LD",
x = "LDH pre-LD (U/L)",
y = "OS (hazard)") +
theme(title = element_text(size=16,face="bold"),legend.title=element_blank())

Hazard of PFS: LDH
Show code
data1 <- filter(dataset, Infused == 1)
dd <- datadist(data1)
options(datadist='dd')
S <- Surv(data1$Days.to.relapse.death.or.DLC, data1$Relapse.or.death)
f <- cph(S ~ LDH.preLD , x=TRUE, y=TRUE,surv=TRUE,data=data1)
model <- Predict(f, LDH.preLD, fun=function(x) exp(x) )
ggplot(as.data.frame(model),aes(x=LDH.preLD, y=yhat)) +
geom_line(
aes()
) +
geom_ribbon(data = model, aes(ymin=lower, ymax=upper), alpha=0.2, linetype=0) +
theme_bw() +
labs(
#title = "Survival by product and LDH pre-LD",
x = "LDH pre-LD (U/L)",
y = "PFS (hazard)") +
theme(title = element_text(size=16,face="bold"),legend.title=element_blank())

Hazard of OS: Largest lesion
Show code
data1 <- dataset
dd <- datadist(data1)
options(datadist='dd')
S <- Surv(data1$Days.to.DLC, data1$Death)
f <- cph(S ~ Largest.lesion, x=TRUE, y=TRUE,surv=TRUE,data=data1)
med <- Quantile(f)
model <- Predict(f, Largest.lesion, fun=function(x) exp(x) )
ggplot(as.data.frame(model),aes(x=Largest.lesion , y=yhat)) +
geom_line() +
geom_ribbon(data = model, aes(ymin=lower, ymax=upper), alpha=0.2, linetype=0) +
theme_bw() +
labs(
#title = "Survival by LDH pre-LD",
x = "Largest lesion (cm)",
y = "OS (hazard)")+
theme(title = element_text(size=16,face="bold"),legend.title=element_blank())

Hazard of OS: Cr
Show code
data1 <- filter(dataset, Infused == 1)
dd <- datadist(data1)
options(datadist='dd')
S <- Surv(data1$Days.to.DLC, data1$Death)
f <- cph(S ~ rcs(cre.preLD,3) , x=TRUE, y=TRUE,surv=TRUE,data=data1)
model <- Predict(f, cre.preLD, fun=function(x) exp(x) )
ggplot(as.data.frame(model),aes(x=cre.preLD, y=yhat)) +
geom_line(
aes()
) +
geom_ribbon(data = model, aes(ymin=lower, ymax=upper), alpha=0.2, linetype=0) +
theme_bw() +
labs(
#title = "Survival by product and pre-LD Cr",
x = "Pre-LD Cr (U/L)",
y = "OS (hazard)") +
theme(title = element_text(size=16,face="bold"),legend.title=element_blank())

CURVE SMOOTHING
ANC Loess modeling – stratified by product
Show code
data1 <- CBCdata %>%
mutate(
CAR.T.Product.Type = recode(CAR.T.Product.Type, "Breyanzi" = "Liso-cel", "Yescarta" = "Axi-cel")
)
ggplot() +
geom_smooth(data = filter(data1, CAR.T.Product.Type == "Liso-cel"), aes(x = day, y = ancx, color = "Liso-cel"), method = "loess", formula = y~x, fill = "#69b3a2", se = TRUE, na.rm = TRUE) +
geom_smooth(data = filter(data1, CAR.T.Product.Type == "Axi-cel"), aes(x = day, y = ancx, color = "Axi-cel"), method = "loess", formula = y~x, fill = "#69b3a2", se = TRUE, na.rm = TRUE) +
labs(
x = "Time relative to infusion (days)",
y = "Absolute neutrophil count (cells/µL)",
color = "Legend"
) +
scale_y_continuous(breaks = c(0, 1000, 2000, 3000, 4000, 5000, 6000)) +
xlim(-5, 50) +
theme_classic() +
theme(legend.position = c(0.8, 0.9)) +
scale_color_manual(values = c("steelblue", "coral2")) +
theme(text = element_text(size = 16))

Plt Loess modeling – stratified by product
Show code
data1 <- CBCdata %>%
mutate(
CAR.T.Product.Type = recode(CAR.T.Product.Type, "Breyanzi" = "Liso-cel", "Yescarta" = "Axi-cel")
)
ggplot() +
geom_smooth(data = filter(data1, CAR.T.Product.Type == "Liso-cel"), aes(x=day, y=TotPlateletCnt/1000, color = "Liso-cel"), method="loess" , formula = y~x, fill="#69b3a2", se=TRUE, na.rm = TRUE) +
geom_smooth(data = filter(data1, CAR.T.Product.Type == "Axi-cel"), aes(x=day, y=TotPlateletCnt/1000, color = "Axi-cel"),method="loess" , formula = y~x , fill="#69b3a2", se=TRUE, na.rm = TRUE) +
labs(x = "Time relative to infusion (days)",
y = "Platelet count (10\u00B3/\u00B5L)",
color = "Legend") +
theme_classic() +
xlim(-5,50) +
scale_color_manual(values = c ("steelblue","coral2")) +
theme(legend.position=c(.8,.9)) +
theme(text = element_text(size = 16))

Ferritin Loess modeling – stratified by CRS
Show code
ferritin.data = filter(labs, day >=-5 & day <=30) %>%
select(day, time, ferritin_ng_ml, uwid) %>%
mutate(
time.percent = sapply( strsplit(time,":"),
function(x) {
x <- as.numeric(x)
x[1]/24
}
),
day = ifelse(day>=0, day + time.percent, day - time.percent),
ferritin = log10(ferritin_ng_ml)
)
ferritin.data <-
left_join(
x = ferritin.data,
y = dataset %>%
select(CAR.T.Product.Type, CRS.grade, uwid, Study.No),
by = "uwid"
)
ggplot() +
geom_smooth(data = filter(ferritin.data, CRS.grade == "3" | CRS.grade == "4"), aes(x=day, y=ferritin_ng_ml, color = "G\u22653 CRS"),method="loess" , formula = y~x , fill="#69b3a2", se=TRUE, na.rm = TRUE) +
geom_smooth(data = filter(ferritin.data, CRS.grade == "1" | CRS.grade == "2"), aes(x=day, y=ferritin_ng_ml, color = "G1-2 CRS"),method="loess" , formula = y~x , fill="#69b3a2", se=TRUE, na.rm = TRUE) +
geom_smooth(data = filter(ferritin.data, CRS.grade == "0"), aes(x=day, y=ferritin_ng_ml, color = "G0 CRS"),method="loess" , formula = y~x , fill="#69b3a2", se=TRUE, na.rm = TRUE) +
labs(x = "Time relative to infusion (days)",
y = "Ferritin (ng/mL)",
color = "Legend") +
theme_classic() +
theme(legend.position=c(.8,.8)) +
theme(text = element_text(size = 16)) +
scale_color_manual(values = c ("coral2","purple","steelblue")) +
coord_cartesian(ylim = c(0, 9000), xlim = c(0, 30))

Ferritin Loess modeling – stratified by ICANS
Show code
ferritin.data = filter(labs, day >=-5 & day <=30) %>%
select(day, time, ferritin_ng_ml, uwid) %>%
mutate(
time.percent = sapply( strsplit(time,":"),
function(x) {
x <- as.numeric(x)
x[1]/24
}
),
day = ifelse(day>=0, day + time.percent, day - time.percent),
ferritin = log10(ferritin_ng_ml)
)
ferritin.data <-
left_join(
x = ferritin.data,
y = dataset %>%
select(CAR.T.Product.Type, CRS.grade, ICANS.grade, uwid, Study.No),
by = "uwid"
)
ggplot() +
geom_smooth(data = filter(ferritin.data, ICANS.grade == "3" | CRS.grade == "4"), aes(x=day, y=ferritin_ng_ml, color = "G\u22653 ICANS"),method="loess" , formula = y~x , fill="#69b3a2", se=TRUE, na.rm = TRUE) +
geom_smooth(data = filter(ferritin.data, ICANS.grade == "1" | CRS.grade == "2"), aes(x=day, y=ferritin_ng_ml, color = "G1-2 ICANS"),method="loess" , formula = y~x , fill="#69b3a2", se=TRUE, na.rm = TRUE) +
geom_smooth(data = filter(ferritin.data, ICANS.grade == "0"), aes(x=day, y=ferritin_ng_ml, color = "G0 ICANS"),method="loess" , formula = y~x , fill="#69b3a2", se=TRUE, na.rm = TRUE) +
labs(x = "Time relative to infusion (days)",
y = "Ferritin (ng/mL)",
color = "Legend") +
theme_classic() +
theme(legend.position=c(.2,.8)) +
theme(text = element_text(size = 16)) +
scale_color_manual(values = c ("coral2","purple","steelblue")) +
coord_cartesian(ylim = c(0, 9000), xlim = c(0, 30))

Ferritin Loess modeling – stratified by response
Show code
ferritin.data = filter(labs, day >=-5 & day <=30) %>%
select(day, time, ferritin_ng_ml, uwid) %>%
mutate(
time.percent = sapply( strsplit(time,":"),
function(x) {
x <- as.numeric(x)
x[1]/24
}
),
day = ifelse(day>=0, day + time.percent, day - time.percent),
ferritin = log10(ferritin_ng_ml)
)
ferritin.data <-
left_join(
x = ferritin.data,
y = dataset %>%
select(CAR.T.Product.Type, CRS.grade, ICANS.grade, uwid, Study.No, Best.CR, Best.PR, Best.PD),
by = "uwid"
)
ggplot() +
geom_smooth(data = filter(ferritin.data, Best.CR == 1), aes(x=day, y=ferritin_ng_ml, color = "CR"),method="loess" , formula = y~x , fill="#69b3a2", se=TRUE, na.rm = TRUE) +
geom_smooth(data = filter(ferritin.data, Best.PR == 1), aes(x=day, y=ferritin_ng_ml, color = "PR"),method="loess" , formula = y~x , fill="#69b3a2", se=TRUE, na.rm = TRUE) +
geom_smooth(data = filter(ferritin.data, Best.PD == 1), aes(x=day, y=ferritin_ng_ml, color = "PD"),method="loess" , formula = y~x , fill="#69b3a2", se=TRUE, na.rm = TRUE) +
labs(x = "Time relative to infusion (days)",
y = "Ferritin (ng/mL)",
color = "Legend") +
theme_classic() +
theme(legend.position=c(.2,.8)) +
theme(text = element_text(size = 16)) +
scale_color_manual(values = c ("coral2","purple","steelblue")) +
coord_cartesian(ylim = c(0, 9000), xlim = c(0, 30))

Ferritin Loess modeling – stratified by product
Show code
ferritin.data = filter(labs, day >=-5 & day <=30) %>%
select(day, time, ferritin_ng_ml, uwid) %>%
mutate(
time.percent = sapply( strsplit(time,":"),
function(x) {
x <- as.numeric(x)
x[1]/24
}
),
day = ifelse(day>=0, day + time.percent, day - time.percent),
ferritin = log10(ferritin_ng_ml)
)
ferritin.data <-
left_join(
x = ferritin.data,
y = dataset %>%
select(CAR.T.Product.Type, CRS.grade, ICANS.grade, uwid, Study.No, Best.CR, Best.PR, Best.PD),
by = "uwid"
)
ggplot() +
geom_smooth(data = filter(ferritin.data, CAR.T.Product.Type == "Breyanzi"), aes(x=day, y=ferritin_ng_ml, color = "Liso-cel"),method="loess" , formula = y~x , fill="#69b3a2", se=TRUE, na.rm = TRUE) +
geom_smooth(data = filter(ferritin.data, CAR.T.Product.Type == "Yescarta"), aes(x=day, y=ferritin_ng_ml, color = "Axi-cel"),method="loess" , formula = y~x , fill="#69b3a2", se=TRUE, na.rm = TRUE) +
labs(x = "Time relative to infusion (days)",
y = "Ferritin (ng/mL)",
color = "Legend") +
theme_classic() +
theme(legend.position=c(.2,.8)) +
theme(text = element_text(size = 16)) +
scale_color_manual(values = c ("coral2","purple","steelblue")) +
coord_cartesian(ylim = c(0, 5000), xlim = c(0, 30))

CONTOUR PLOTS
Contour plot for largest lesion and LDH pre-LD
Show code
data1 <- filter(dataset, CAR.T.Product.Type == "Breyanzi")
dd <- datadist(data1)
options(datadist='dd')
S <- Surv(data1$Days.to.DLC/30, data1$Death)
f <- cph(S ~ Largest.lesion * LDH.preLD , x=TRUE, y=TRUE,surv=TRUE,data=data1)
med <- Quantile(f)
data.frame(Predict(f,Largest.lesion,LDH.preLD,fun=function(x) med(lp=x))) %>%
ggplot() +
geom_contour_filled(aes(Largest.lesion,LDH.preLD, z = yhat)) +
theme_classic() +
labs(title = "Liso-cel",
x = "Largest lesion (cm)",
y = "LDH pre-LD (U/L)",
fill="Median survival (months)") +
coord_cartesian(xlim = c(0, 10), ylim = c(100, 700))
Show code
data1 <- filter(dataset, CAR.T.Product.Type == "Yescarta") %>%
select(Largest.lesion, LDH.preLD, Days.to.DLC, Death
)
dd <- datadist(data1)
options(datadist='dd')
S <- Surv(data1$Days.to.DLC/30, data1$Death)
f <- cph(S ~ Largest.lesion * LDH.preLD , x=TRUE, y=TRUE,surv=TRUE,data=data1)
med <- Quantile(f)
data.frame(Predict(f,Largest.lesion,LDH.preLD,fun=function(x) med(lp=x))) %>%
ggplot() +
geom_contour_filled(aes(Largest.lesion,LDH.preLD, z = yhat)) +
theme_classic() +
labs(title = "Axi-cel",
x = "Largest lesion (cm)",
y = "LDH pre-LD (U/L)",
fill="Median survival (months)") +
coord_cartesian(xlim = c(0, 10), ylim = c(100, 700))

Contour plot for Age and ALC pre-LD
Show code
data1 <- filter(dataset, Infused == 1)
dd <- datadist(data1)
options(datadist='dd')
S <- Surv(data1$Days.to.DLC, data1$Death)
f <- cph(S ~ Age * ALC.preLD , x=TRUE, y=TRUE,surv=TRUE,data=data1)
med <- Quantile(f)
data.frame(Predict(f,Age,ALC.preLD,fun=function(x) med(lp=x)/365.25)) %>%
ggplot() +
geom_contour_filled(aes(Age,ALC.preLD, z = yhat)) +
theme_classic() +
labs(title = "Survival: ALC pre-LD and Age",
x = "Age (years)",
y = "ALC pre-LD (10\U00B3/\U00B5L)",
fill="Median survival (years)")

Swimmer’s plot
Swimmer plot
Show code
swimmer_data = as.data.frame(read_excel(path = "Swimmer.xlsx")) %>%
mutate(
Response_start = Response_start/30,
Response_end = Response_end/30,
Time = Time/30,
Product = recode(Product, "Breyanzi" = "Liso-cel","Yescarta"="Axi-cel"),
Response = factor(Response, levels = c("CR","PR","SD", "PD"))
)
pastel1_palette <- brewer.pal(4, "Pastel1")[c(3,2,4,1)]
swimmer <- swimmer_plot(df=filter(swimmer_data, !is.na(Response) ),
id="Number",
end= "Response_end",
name_fill="Response",
stratify = "Product",
) +
scale_fill_manual(values = pastel1_palette) +
swimmer_arrows(df_arrows = filter(swimmer_data,!is.na(Continued_response) ),
id="Number",
arrow_start="Response_end",
name_col = 'Response',
type = "closed", cex=.5,
arrow_positions = c(1,6)
)+
scale_color_manual(name="Response",values=pastel1_palette,drop=FALSE) +
swimmer_points(df_points= filter(swimmer_data,!is.na(Event) ) ,id='Number',name_shape = "Event", time='Time',size=1,fill='white',col="black") +
scale_y_continuous(name = "Time since infusion (Months)",breaks = seq(0,10000,by=12)) +
guides(fill = guide_legend(title = "Response"), colour = FALSE) # Hide the legend for arrows
swimmer
